Nginx学习笔记:

Nginx学习笔记: 文章目录Nginx学习笔记1.正向代理和反向代理2.负载均衡和动静分离3.安装nginx4.nginx常用命令5.nginx简单实战6.nginx配置文件部分介绍7.nginx解决部分问题8.nginx解决跨域问题9.跨域问题处理方法1:nginx反向代理-如序号8部分所示方法2:CROS跨域资源共享方法3:jsonp方法4:代理服务器方法5:iframepostMessage父子窗口实现数据传递前后端分离简单例子Nginx学习笔记1.正向代理和反向代理正向代理客户端代理位于用户和目标服务器之间正向代理客户端向代理服务器发送一个请求并制定目标客户端知道目标服务器端存在进而代理服务器向目标服务器转发请求并将获取的内容返回给客户端的过程特点正向代理客户端发送的请求中有目标服务器的信息属于是指定访问适用场景访问控制限制特定用户或特定ip地址的访问权限隐藏真实客户端加速访问可以缓存常用的请求结果减少服务器的负载突破访问限制可以绕过网络限制访问被封锁的网站或者服务反向代理服务端代理位于目标服务器和用户之间反向代理代理服务器接受客户端的请求然后根据请求转发给内部网络上的服务器并将服务器上获取的结果返回给客户端客户端不知道目标服务器的存在而是认为代理服务器为目标服务器特点反向代理客户端将请求发送给代理服务器由代理服务器来判断应该访问哪个目标服务器适用场景负载均衡可以将请求发送到多个服务器提高性能隐藏真实服务器缓存静态内容ssl加密保证数据的安全传输2.负载均衡和动静分离轮询无权重固定加权轮询根据权重调整访问概率iphash对请求的ip进行hash操作根据hash的结果将同一个ip的请求发送给同一个服务器来处理可以解决session不共享的问题动静分离3.安装nginx官网下载地址nginx: downloadwindow安装解压关注conf中的nginx.conf配置文件文件点击nginx.exe启动可以用命令终端运行nginx.exe测试连接访问默认配置的端口linux安装将下载好的nginx.tar.gz文件用finalshell传到linux虚拟机中解压文件tar-zxvfnginx-1.28.0.tar.gz执行文件[rootlocalhost nginx-1.28.0]# ./configure[rootlocalhost nginx-1.28.0]# make[rootlocalhost nginx-1.28.0]# make install#若出现make: *** 没有规则可以创建“default”需要的目标“build”。 停止。#则通过执行以下代码进行重新安装nginx所需依赖完成后再configure和make[rootlocalhost nginx-1.28.0]# yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel自动安装也可以用yum安装nginxyum install nginx测试是否安装成功[rootlocalhost nginx-1.28.0]# whereis nginxnginx:/usr/local/nginx[rootlocalhost nginx-1.28.0]# cd/usr/local/nginx[rootlocalhost nginx]# ll 总用量4drwxr-xr-x.2root root40967月1407:41conf drwxr-xr-x.2root root407月1407:41html drwxr-xr-x.2root root67月1407:41logs drwxr-xr-x.2root root367月1407:41sbin[rootlocalhost nginx]# cd sbin/[rootlocalhost sbin]# ll 总用量7752-rwxr-xr-x.1root root39684807月1407:41nginx-rwxr-xr-x.1root root39684807月1407:40nginx.old[rootlocalhost sbin]#./nginxsudo systemctl stop firewalld sudo systemctl disable firewalld4.nginx常用命令启动./nginx暂停./nginx -s stop安全退出./nginx -s quit重新加载配置文件./nginx -s reload(修改配置文件要生效得用该命令)查看nginx进程ps aux|grep nginxlinux常用端口命令5.nginx简单实战配置文件三个模块全局配置 event http--------------------全局配置----------------------------- #user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; --------------------event----------------------------- events { worker_connections 1024; #限制最大连接数为1024 } --------------------http----------------------------- http { --------1.server------- server { listen 80; server_name localhost; #代理 80端口会进入该端口 } server { listen 443; server_name localhost; #代理 443端口会进入该端口 } http 配置 --------2.location------- loctaion / { //xxx 128.xxx } loctaion /admin { //xxx 47 } #如上述两个location 当请求为www.study.com/则访问128.xxx #当请求为www.study.com/admin则访问47 loctaion / { root html; index index.html index.htm; #定义代理 只要是/根目录的请求则代理到study负载均衡中定义的中 proxy_pass http://study } --------3.负载均衡------ upsteram xxx{ #负载均衡配置 下述的例子假定有两个服务器8080和8081 } upsteram study{ server 127.0.0.1:8080 weight1; server 127.0.0.1:8081 weight1; #如上负载均衡 两个服务的权重相同则为轮询 可以修改weight 值越大访问可能性越大 server1的访问概率为 weight1/(weight1weight2) } }简单例子实现代理和负载均衡配置好nginx后重新启动nginx则输入http://localhost/admin 无需端口号则可以根据负载均衡的结果访问8081或者8080介绍http { server { listen 80; server_name localhost; } #当访问localhost/则会根据负载均衡的结果来选择服务器 loctaion /admin { root html; index index.html index.htm; proxy_pass http://study } #配置两个端口的负载均衡 upsteram study{ server 127.0.0.1:8080 weight1; server 127.0.0.1:8081 weight1; } }6.nginx配置文件部分介绍参考网站nginx详细参数配置(史上最全) - hanease - 博客园 (cnblogs.com)参数介绍(官网下载的nginx.conf)Part1:工作进程配置和用户配置user 默认为nobodyuser的作用为指定执行nginx的worker process的用户linux里所有程序都是文件都具有权限问题这个指定的用户对特定的文件有没有权限访问或执行worker_processes工作进程的数量可以根据服务器的CPU核心数进行调整例如如果服务器有4个CPU核心可以将worker_processes设置为4一般一个进程足够了你可以把连接数设得很大。如果有SSL、gzip这些比较消耗CPU的工作而且是多核CPU的话可以设为和CPU的数量一样worker_connections单个工作进程可以允许同时建立外部连接的数量。默认值为1024worker_rlimit_nofile用于设置每个worker进程允许打开的最大文件描述符数量使用场景高并发连接 需要处理大量的并发连接每个连接都需要一个文件描述符静态文件服务用于提供大量的静态文件服务反向代理处理多个后端服务器的连接可以确保有足够的文件描述符来管理这些连接user nobody; #工作进程的数量 worker_processes 1; #配置Nginx worker进程最大打开文件数 默认为0 worker_rlimit_nofile65535 events { # 单个进程允许的客户端最大连接数 worker_connections 1024; } #worker_rlimit_nofile 的值与 worker_processes 和 worker_connections 的值相匹配 #如worker_processes为2 worker_connections 为1024则一般设置worker_rlimit_nofile为2048Part2:错误日记关键字error_log不可改变日记文件:可以指定任意存放日志的目录错误日记级别:debug | info | notice | warn | error | crit | alert | emerg 级别越高记录学习越少低级别的消耗i/o越大升序为从左到右递增#默认 由关键字 日记文件 错误日记级别组成 error_log logs/error.log; error_log logs/error.log notice; error_log logs/error.log info;Part3:httpinclude mime.types用于引入MIME类型配置文件MIME类型用于指定文件的类型以便浏览器可以正确地解析和显示文件该文件定义了各种文件扩展名与MIME类型之间的映射关default_type application/octet-stream是一种常见的 MIME 类型用于表示任意类型的二进制数据通常用于未知文件类型或需要下载的文件类型http { include mime.types; default_type application/octet-stream; ... }Part4log_format(不展开解析有需要再查看文档)和传输参考文档Nginx配置中的log_format用法梳理设置详细的日志格式 - 散尽浮华 - 博客园 (cnblogs.com)log_format:用来设置日志格式access_log:用来指定日志文件的存放路径、格式和缓存大小sendfile用于提高静态文件传输的性能开启后可避免了数据在用户态和内核态之间的多次拷贝一般数据文件传输需要结果多次拷贝从硬盘拷贝到内核缓冲区 从内核缓冲区拷贝到用户缓冲区 从用户缓冲区拷贝到内核socket缓冲区 从内核socket缓冲区拷贝到协议引擎开启sendfile数据直接从硬盘拷贝到内核缓冲区再从内核缓冲区拷贝到内核socket缓冲区避免了用户态和内核态之间的切换gzip用于压缩HTTP响应内容从而减少数据传输的带宽消耗和响应时间提高网站的性能和速度参考文档:Nginx开启Gzip压缩功能附详细解释测试是否开启了压缩_判断nginx是否开启gzip-CSDN博客http { #用来设置日志格式 log_format main $remote_addr - $remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for; #用来指定日志文件的存放路径、格式和缓存大小 access_log logs/access.log main; # 开启高效文件传输模式 sendfile on; #确保数据包在发送前已充分填满 tcp_nopush on; # 提高数据包传输的实时性 tcp_nodelay on; # 链接超时时间自动断开 keepalive_timeout 0; keepalive_timeout 65; # 启用gzip压缩 gzip on; }Part5:httphttp { # 虚拟主机 #例子1 #当nginx接到请求后会匹配其配置中的service模块 #匹配方法就是靠请求携带的host和port正好对应其配置中的server_name 和listen server { #如访问localhost只有端口为80时可以省略或者localhost:80就会进入访问网站 #80端口是服务器提供网站访问服务的默认端口 #即为输入server_namelisten就可以用代理服务器代理服务器根据配置转发访问目标服务器 listen 80; server_name localhost; # 浏览器访问域名 #方式1本地页面出现对应的错误就会跳转到指定的url或者文件目录(需要注意必须有50x.html这个页面) error_page 500 502 503 504 /50x.html; error_page 404 /404.html; #即为当错误代码是502等50开头的错误相当于访问http://localhost:80/50x.html #进而传送到location /50x.html location /50x.html { #目标资源前缀 /usr/share/nginx/html/*** root /usr/share/nginx/html; } #方式2错误跳转到指定的页面 error_page 500 502 503 504 https://www.baidu.com; #方式3错误提示 error_page 404 jump_to_error; location jump_to_error { default_type text/plain; return 404 Not Found Page...; } # 路由 location / { root html; index index.html index.htm; #入口文件 Nginx会根据文件的枚举顺序来检查直到查找的文件存在该指令拥有默认值index index.html 即如果没有给出index默认初始页为index.html } } #例子2:alias 多用于静态文件 配置多个serve server { listen 8000; listen somename:8080; server_name somename alias another.alias; #当请求http://somename/123/abc/logo.png时会返回会返回/ABC/abc路径下的文件即为用/ABC代替/123/abc/ location /123/abc/ { alias /ABC; index index.html; } #当请求http://somename/123/abc/logo.png时会返回/ABC/123/abc路径下的文件 location /123/abc/ { root /ABC; index index.html; } } # HTTPS server # #server { # listen 443 ssl; # server_name localhost; # ssl_certificate cert.pem; # ssl_certificate_key cert.key; # ssl_session_cache shared:SSL:1m; # ssl_session_timeout 5m; # ssl_ciphers HIGH:!aNULL:!MD5; # ssl_prefer_server_ciphers on; # location / { # root html; # index index.html index.htm; # } #} # 引入其他的配置文件 include servers/*; }7.nginx解决部分问题根据文件类型设置过期时间location ~.*\.css$ { expires 1d; break; } location ~.*\.js$ { expires 1d; break; } location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { access_log off; expires 15d; #保存15天 break; }静态文件压缩server { # 开启gzip 压缩 gzip on; # 设置gzip所需的http协议最低版本 HTTP/1.1, HTTP/1.0 gzip_http_version 1.1; # 设置压缩级别压缩级别越高压缩时间越长 1-9 gzip_comp_level 4; # 设置压缩的最小字节数 页面Content-Length获取 gzip_min_length 1000; # 设置压缩文件的类型 text/html) gzip_types text/plain application/javascript text/css; }8.nginx解决跨域问题使用server_name和location分别代理到不同不同地址即可例子前端server域名http://xx.domain后端server域名https://study.com若http://xx.domain向https://study.com发送请求则会遇到跨域问题解决思路创建一个sevrer设置server_name为xx.domain之后再location中设置/其中设置代理为https://study.com## 配置反向代理的参数 server { listen 8080; server_name xx_domain ## 1. 用户访问 http://xx_domain则反向代理到 https://github.com location / { proxy_pass https://study.com proxy_redirect off; proxy_set_header Host $host; # 传递域名 proxy_set_header X-Real-IP $remote_addr; # 传递ip proxy_set_header X-Scheme $scheme; # 传递协议 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }nginx反向代理的各参数proxy_pass将请求转发到指定的URL。proxy_set_header设置转发请求的头部信息。location / { proxy_pass http://localhost:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }proxy_redirect:proxy_redirect指令会禁用所有的 URL 重写规则location /some/path/ { proxy_pass http://upstream_server; proxy_redirect off; } #当设置为 off 时proxy_redirect 指令会禁用所有的 URL 重写规则。这意味着 Nginx 将不会修改从上游服务器返回的任何重定向 URL。例如如果上游服务器返回一个指向 http://localhost:8000/two/some/uri/ 的重定向而 Nginx 配置中有 proxy_redirect off;那么这个 URL 将不会被修改客户端将收到原始的重定向 URL。9.跨域问题处理方法1:nginx反向代理-如序号8部分所示该部分不做演示用servername和location来处理即可推荐方法2:CROS跨域资源共享方法通过服务器设置响应头允许跨域访问推荐Origin 协议 域名 端口 两个 URL 的协议 域名 端口一致反之则是跨域参考网站什么是跨域跨域解决方法-CSDN博客注意普通跨域请求只需服务器端设置Access-Control-Allow-Origin带cookie跨域请求前后端都需要进行设置简单演示客户端处理CROS//jsfunctionsendAuthRequestToCrossOrigin(){varxhrnewXMLHttpRequest();xhr.onreadystatechangefunction(){if(this.readyState4this.status200){document.getElementById(demo).innerHTMLthis.responseText;}};xhr.open(GET,要放开的地址,true);xhr.setRequestHeader(Content-Type,application/x-www-form-urlencoded)// 前端设置是否带cookiexhr.withCredentialstrue;xhr.send();}//jquey$.ajax({url:要放开的地址,type:get,data:{},xhrFields:{withCredentials:true// 前端设置是否带cookie},crossDomain:true,// 会让请求头中包含跨域的额外信息但不会含cookie});//vue-resourceVue.http.options.credentialstrue//axiosaxios.defaults.withCredentialstrueSpringboot使用CrossOrigin标签CrossOriginRestControllerpublicclassTestCROSextendsBaseController{.....}使用过滤器ComponentpublicclassCORSFilterimplementsFilter{OverridepublicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{HttpServletResponseres(HttpServletResponse)response;res.addHeader(Access-Control-Allow-Credentials,true);res.addHeader(Access-Control-Allow-Origin,*);res.addHeader(Access-Control-Allow-Methods,GET, POST, DELETE, PUT);res.addHeader(Access-Control-Allow-Headers,Content-Type,X-CAF-Authorization-Token,sessionToken,X-TOKEN);if(((HttpServletRequest)request).getMethod().equals(OPTIONS)){response.getWriter().println(ok);return;}chain.doFilter(request,response);}Overridepublicvoiddestroy(){}Overridepublicvoidinit(FilterConfigfilterConfig)throwsServletException{}}//允许所有访问//Access-Control-Allow-Origin: *//允许特定访问//Access-Control-Allow-Origin: 请求地址//允许凭据请求访问//Access-Control-Allow-Origin: 请求地址 Access-Control-Allow-Credentials: true//允许特定方法和头部//Access-Control-Allow-Origin: 请求地址 Access-Control-Allow-Methods: GET, POST, PUT, DELETE Access-Control-Allow-Headers: Content-Type, Authorization- Configure配置类 java Configuration public class WebMvcConfig extends WebMvcConfigurerAdapter { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOrigins(*) .allowedMethods(POST, GET, PUT, OPTIONS, DELETE) //针对header单独设置不然无法获取header中的请求信息前端也无法拿到响应中的 // header信息OPTIONS请求也会经过拦截器在进行登录拦截时候要注意特殊处理 .allowedHeaders(*) .exposedHeaders(access-control-allow-headers, access-control-allow-methods, access-control-allow-origin, access-control-max-age, X-Frame-Options) // 表明在3600秒内不需要再发送预检验请求可以缓存该结果 .maxAge(3600) .allowCredentials(true); } }方法3:jsonp方法通过方法4:代理服务器方法通过代理将跨域请求转为同源请求。原理客户端发送请求到代理服务器客户端的请求首先发送到代理服务器而不是直接发送到目标服务器。代理服务器转发请求代理服务器接收到请求后将其转发给目标服务器。目标服务器处理请求并响应目标服务器处理请求并将响应发送回代理服务器。代理服务器返回响应代理服务器接收到目标服务器的响应后再将其转发回客户端例子在vue.conf.js中配置module.exports{devServer:{proxy:{/api:{target:http://172.**.**.**:9000,//要代理的域名changeOrigin:true,//允许跨域pathRewrite:{^/api:}// 这个是定义要访问的路径名字随便写}}}}///api/getUserMsg 相当于 http://172.**.**.**:9000/getUserMsg//多端口代理devServer:{//代理列表proxy:{/mps-ss:{target:http://172.**.**.**:9001,changeOrigin:true,pathRewrite:{^/mps1:/mps1}},/mps-fileApi:{target:http://172.**.**.**:9002,changeOrigin:true,pathRewrite:{^/mps2:/}}}//上下两个pathRewrite对比会发现匹配^/mps1会等于 /mps1另一个是 匹配^/mps2会等于 /方法5:iframepostMessage父子窗口实现数据传递使用场景数据传递页面和其打开的新窗口的数据传递多窗口之间消息传递页面与嵌套的iframe消息传递事件默认参数e.source: 消息源 发送消息的窗口/iframee.origin:发送消息的消息源urie.data:发送过来的数据例子window.parent属性返回当前窗口的直接父窗口window.top 返回窗口对象层次结构中的最顶层窗口例子1:子窗口发送数据给父窗口//子窗口 端口为8090bodydiv窗口2/divscriptletparentData{type:1,data:hello world};window.parent.postMessage(parentData,*);// 自动调用open会被浏览器拦截需要手动取消拦截// 或者添加一个点击事件通过手动调用来打开新窗口/script/body//父窗口 端口为8089bodydiv窗口1/diviframesrchttp://127.0.0.1:8090/index.htmlframeborder1dm_iframenamem_iframe/iframescript//监听window的messagewindow.addEventListener(message,receiveMessage,false);functionreceiveMessage(event){console.info(主页接受到的消息)console.info(origin,event.origin)console.info(mesage,event.data)}/script/body例子2:夫窗口发数据给子窗口//父窗口 端口为8089bodydiv窗口1/diviframesrchttp://127.0.0.1:8090/index.htmlframeborder1idm_iframenamem_iframe/iframescriptletm_iframedocument.getElementById(m_iframe);m_iframe.onloadfunction(){// 向domain2发送跨域数据m_iframe.contentWindow.postMessage(发送给内页的消息,http://127.0.0.1:8090);};/script/body//子窗口 端口为8090bodydiv窗口2/divscriptwindow.addEventListener(message,receiveMessage,false);functionreceiveMessage(event){console.info(内页接受到的消息)console.info(origin,event.origin)console.info(mesage,event.data)}/script/body前后端分离简单例子