服务器
服务器
服务器是一种提供高效计算的机器,与普通的PC主机相比,具有可观的稳定性,高并发性,可扩展性。
互联网任何一个应用都是以服务器为基础设施的,没有服务器我们就无法访问网络上的任何内容,只能使用单机的应用。例如网站,我们访问的任何一个网站都是保存在某个服务器上的,域名被DNS(域名解析服务器)解析到IP地址后,浏览器就能通过IP地址访问对应的服务器资源了。
就好比:服务器是人的家,人名相当于域名(不可重名),身份证号相当于IP地址。通过人名搜索到身份证号,通过身份证号获取到家的地址。
Web服务器
Web服务器不再是一种硬件设施,而是一种部署在服务器上的软件应用,它服务于各种网络请求,将网络请求进行处理,分发。
所以Web服务器的处理能力很大程度决定了该网站的并发能力。著名的Web服务器有:Apache Nginx
Web应用服务器
Web应用服务器是专门处理逻辑代码的服务器,同时还具有了处理网络请求的能力,一般为了提高并发能力,会在Web应用服务器上套一层Web服务器。
例如:Tomcat uwsgi gunicorn,后两个是Python的Web应用服务器,专门处理Python的逻辑代码。
联系
其中Web服务器和Web应用服务器都部署在服务器上。
Nginx服务器
Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。其主要特点如下:
- 轻量级 并发能力强
- 支持处理静态资源,以减少应用服务器的压力
- 负载均衡
负载均衡
大型的网站应用网站应用往往是由无数个服务器服务的,就像淘宝这种,单靠一个是不可能承受的了如此大的并发量,因此有了负载均衡。负载均衡又分为硬负载均衡和软负载均衡,硬负载均衡是通过硬件的方式实现负载均衡,比如F5,成本都比较昂贵,软负载均衡则是通过软件的方式实现,比如Nginx和Apache。
所谓负载均衡就是将多个请求分发到不同的服务器上去,每个服务器都有处理请求和逻辑的应用服务器,以此来提高并发量。
下面使用Nginx来实现负载均衡配置
配置Nginx需要到/etc/nginx/nginx.conf文件内进行编辑
http {
##http的配置
server {
listen 80;//监听端口
server_name 域名;
location / {
proxy_pass http://lca;
}
}
upstream lca {//采用轮询方式,依次将请求转发到各个服务器
server 192.168.1.1:5000;
server 192.168.1.2:5000;
server 192.168.1.3:5000;
}
}
上面是采用轮询的方式实现端口转发 负载均衡,还有几种方式实现:
- 权重方式:指定每个服务的权重比例,weight和访问比率成正比,通常用于后端服务机器性能不统一,将性能好的分配权重高来发挥服务器最大性能.
upstream lca {
server 192.168.1.1:5000 weight=1;
server 192.168.1.2:5000 weight=2;
server 192.168.1.3:5000 weight=3;
}
- iphash
每个请求都根据访问ip的hash结果分配,经过这样的处理,每个用户固定访问一个后端服务。
upstream lca {//权重与iphash结合
ip_hash
server 192.168.1.1:5000 weight=1;
server 192.168.1.2:5000 weight=2;
server 192.168.1.3:5000 weight=3;
}
解决跨域问题
跨域请求问题
为了提高浏览器的安全性,引入了跨域限制,也就是同源策略。
所谓源:如果两个页面(接口)的协议,端口或者域名都相同,那么两个页面就有相同的源。如果在同一个页面访问不同源的资源,则会出现500错误。
- 浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域
- 跨域限制主要是为了安全考虑
前端在请求后端资源时,往往会出现错误代码500的情况。
nginx解决跨域问题
解决跨域问题的方式有很多,在这里介绍通过nginx来解决跨域问题。
上面说到客户端浏览器同时请求服务器的不同资源若不是同源就会引发同源策略问题,那要是服务器请求服务器呢?那么照这个思路就想到了nginx的反向代理。
我们可以使用nginx的反向代理,将不同源的服务器集中到一个nginx web服务器下,也就是通过nginx来反向代理各个服务器。
server
{
listen 80;
server_name cola666.top;
// =/ 表示精确匹配路径为/的url,真实访问为http://localhost:8000
location = / {
proxy_pass http://localhost:8000;
}
//当匹配到/a的url自动去localhost:8000
location /a{
proxy_pass http://localhost:8001;
}
location /baidu/ {
proxy_pass http://www.baidu.com/;
}
}
- 当有请求www.cola666.top的资源时,服务器接收到,会自动将请求内容交给localhost:8000web服务器处理。
- 当有请求www.cola666.top/a下的资源时,服务器接收到,会自动将请求内容交给localhost:8001web服务器处理。
- 当有请求www.cola666.top/baidu/下的资源时,服务器接收到,会请求百度的服务器资源。
虽然请求同源url,但实际上nginx帮助我们转发到其他web服务器,所以实际上访问的是非同源url资源,以实现跨域问题!
location匹配规则
- 当一个url匹配到多个location时,nginx将请求转发给匹配最长的location来处理
- 代理
location /b/ {
proxy_pass http://www.baidu.com/;
}
location /b/ {
proxy_pass http://www.baidu.com;
}
二者的区别为后者会将location中的/b/也添加进url中,比如,后者则代理到http://www.baidu.com/b/xxx,前者则是http:///www.baidu.com/xxx
下面为一个比较简易的完整的nginx配置
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
location / {
proxy_pass http://localhost:8080;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
最后附加一个全面的nginx配置,包括静态资源缓存,负载均衡,Https,等等
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
#自定义的日志格式
log_format main '[($remote_addr) - ($remote_user [$time_local]) $request" '
'($status) '
'($http_user_agent)($http_x_forwarded_for)'
'($upstream_addr) ($upstream_response_time) ($request_time) ]';
proxy_cache_path /data/nginx/tmp-test levels=1:2 keys_zone=tmp-test:100m inactive=7d max_size=10g;
access_log /var/log/nginx/access.log main;
gzip on;
gzip_min_length 1k;
gzip_buffers 16 64k;
gzip_http_version 1.1;
gzip_comp_level 4;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css;
gzip_vary on;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf;
#allow to access by the same origin
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Credentials' 'true';
upstream zzm {
server localhost:8000;
#server locahost:8001;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location /static{
alias /var/static;
}
location /{
proxy_cache tmp-test;
proxy_cache_key $uri;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept";
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
#include uwsgi_params;
proxy_pass http://zzm;
# if django be used socket model to start up,using uwsgi of the following
#uwsgi_pass 127.0.0.1:8000;
#uwsgi_read_timeout 180;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header REMOTE_ADDR $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
real_ip_recursive on;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
#配置https
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name cola666.top;
root /usr/share/nginx/html;
ssl_certificate /var/xxx.pem;#ssl两个证书路径
ssl_certificate_key /var/xxx.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
#静态资源路径
location /static{
alias /var/static;
}
location / {
#缓存路径
proxy_cache tmp-test;
proxy_cache_key $uri;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept";
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
#include uwsgi_params;
#uwsgi_pass 127.0.0.1:8000;
proxy_pass http://zzm;
proxy_redirect off;
#将客户端ip地址交给服务器后端
proxy_set_header Host $host;
proxy_set_header REMOTE_ADDR $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
real_ip_recursive on;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}