Docker 安装Nginx与配置Nginx

种地  金牌会员 | 2024-6-21 13:18:27 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 557|帖子 557|积分 1671

媒介

1.什么是nginx

  1.    Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,ginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好
复制代码
2.为什么使用nginx

在传统的Web项目中,并发量小,用户使用的少。以是在低并发的情况下,用户可以直接访问tomcat服务器,然后tomcat服务器返回消息给用户。
  1. 用户访问<-->Tomcat服务器
复制代码
而在互联网项目下,因单个tomcat默认并发量有限制。假如请求量过大,会产生如下题目:
  1. Tomcat8 默认配置的最大请求数是 150,也就是说同时支持 150 个并发,当然了,也可以将其改大。
  2. 当某个应用拥有 250 个以上并发的时候,应考虑应用服务器的集群。
  3. 具体能承载多少并发,需要看硬件的配置,CPU 越多性能越高,分配给 JVM 的内存越多性能也就越高,但也会加重 GC 的负担。
  4. 操作系统对于进程中的线程数有一定的限制:
  5. Windows 每个进程中的线程数不允许超过 2000
  6. Linux 每个进程中的线程数不允许超过 1000
  7. Tomcat的最大并发数是可以配置的,实际运用中,最大并发数与硬件性能和CPU数量都有很大关系的。更好的硬件,更多的处理器都会使Tomcat支持更多的并发。
  8. maxThreads="150" 最大并发数
  9. minSpareThreads="10"///初始化时创建的线程数
  10. maxSpareThreads="500"///一旦创建的线程超过这个值,Tomcat就会关闭不再需要的socket线程。
复制代码

3.高并发

是互联网分布式体系架构计划中必须考虑的因素之一,它通常是指,通过计划保证体系可以或许同时并行处理许多请求。
高并发相关常用的一些指标有响应时间(Response Time),吞吐量(Throughput),每秒查询率QPS(Query Per Second),并发用户数等。
响应时间: 体系对请求做出响应的时间。比方体系处理一个HTTP请求需要200ms,这个200ms就是体系的响应时间。
吞吐量: 单位时间内处理的请求数量。
QPS: 每秒响应请求数。在互联网范畴,这个指标和吞吐量区分的没有这么显着。
并发用户数: 同时承载正常使用体系功能的用户数量。
高可用(High Availability)
通常来形貌一个体系颠末专门的计划,从而减少停工时间,而保持其服务的高度可用性。
(不绝都能用 99.9999%)
高性能:
是指服务响应时间快,(CPU/处理器/内存)特殊是在高并发下响应时间不会急剧增加。
4.Nginx特点:

高并发、高性能,
可扩展性好,
高可靠性,
热部署,
BSD许可证。
对于反向代理和正向代理这篇文章讲的很细致了
正向代理和反向代理
提示:以下是本篇文章正文内容,下面案例可供参考
一、docker安装nginx

docker run -d --name mynginx --restart=always -v /home/nginx/nginx.conf:/etc/nginx/nginx.conf -v /home/nginx/default.conf:/etc/nginx/conf.d/default.conf -p 8080:80 -t nginx
提示:我是安装在/home/nginx目录下的,以是先建这个目录 mkdir nginx。
-v
表示文件挂载,用法: -v 本地挂载文件:容器目标文件。
-d
容器将在背景以守护进程的形式运行,而不会阻塞终端。
–restart=always
运行容器时使用–restart参数可以指定一个restart计谋,来指示在退出时容器应该如何重启或不应该重启。
no – 容器退出时不要自动重启。这个是默认值。
on-failure[:max-retries] – 只在容器以非0状态码退出时重启。可选的,可以退出docker daemon尝试重启容器的次数。
always – 不管退出状态码是什么始终重启容器。当指定always时,docker daemon将无限次数地重启容器。容器也会在daemon启动时尝试重启,不管容器当时的状态如何。
unless-stopped – 不管退出状态码是什么始终重启容器,不过当daemon启动时,假如容器之前已经为停止状态,不要尝试启动它。
检察nginx版本可以通过命令 docker inspect nginx 检察

二、Nginx配置简介

1.文件解说

  1. 文件挂载到本地后会看到两个文件
复制代码
  1. default.conf  nginx.conf
复制代码
default.conf:
默认的 nginx 配置文件
nginx.conf:
nginx的主配置文件,它包罗了全局配置和一些默认的设置,影响整个nginx服务器的行为,这个文件通常用于配置一些全局性的参数。
2.nginx.conf

  1. cat nginx.conf
复制代码
  1. user  nginx;
  2. #Nginx 主配置文件中的一个重要选项,用于指定 Nginx 服务器的工作进程数。
  3. #每个工作进程都是一个独立的 Nginx 进程,用于处理客户端请求
  4. #Nginx 将根据可用的 CPU 核数动态确定工作进程的数量。这样可以更好地利用多核系统的性能。
  5. #例如:worker_processes  4,配置4个线程
  6. worker_processes  auto;
  7. error_log  /var/log/nginx/error.log notice;
  8. pid        /var/run/nginx.pid;
  9. #配置与连接处理相关的参数,如最大连接数
  10. events {
  11.     worker_connections  1024;
  12. }
  13. #配置 HTTP 服务器的参数,设定http服务器,利用它的反向代理功能提供负载均衡支持
  14. http {
  15.     #引入其他配置文件,通常用于模块化配置。在conf/mime.types查看支持哪些类型
  16.     include       /etc/nginx/mime.types;
  17.     default_type  application/octet-stream;
  18.     #配置日志格式
  19.     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
  20.                       '$status $body_bytes_sent "$http_referer" '
  21.                       '"$http_user_agent" "$http_x_forwarded_for"';
  22.     access_log  /var/log/nginx/access.log  main;
  23.    
  24.      #是否使用sendfile传输文件
  25.     sendfile        on;
  26.     #tcp_nopush     on;
  27.     #连接超时时间
  28.     keepalive_timeout  65;
  29.     #gzip  on;
  30.     include /etc/nginx/conf.d/*.conf;
  31. }
复制代码
3.default.conf

  1. server {
  2.     ##配置监听端口
  3.     listen       80;
  4.     listen  [::]:80;
  5.     #配置服务器名
  6.     server_name  localhost;
  7.     #access_log  /var/log/nginx/host.access.log  main;
  8.     location / {
  9.         root   /usr/share/nginx/html;
  10.         index  index.html index.htm;
  11.     }
  12.    
  13.     #配置404页面
  14.     #error_page  404              /404.html;
  15.     # redirect server error pages to the static page /50x.html
  16.    
  17.     #配置50x页面
  18.     error_page   500 502 503 504  /50x.html;
  19.     #精确匹配
  20.     location = /50x.html {
  21.         #root是配置服务器的默认网站根目录位置,在nginx目录下html
  22.         root   /usr/share/nginx/html;
  23.     }
  24.    
  25.     #这是转发php脚本代理到127.0.0.1:80的Apache侦听
  26.     # proxy the PHP scripts to Apache listening on 127.0.0.1:80
  27.     #
  28.     #location ~ \.php$ {
  29.     #    proxy_pass   http://127.0.0.1;
  30.     #}
  31.     # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
  32.     #
  33.     #location ~ \.php$ {
  34.     #    root           html;
  35.     #    fastcgi_pass   127.0.0.1:9000;
  36.     #    fastcgi_index  index.php;
  37.     #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
  38.     #    include        fastcgi_params;
  39.     #}
  40.     # deny access to .htaccess files, if Apache's document root
  41.     # concurs with nginx's one
  42.     #
  43.     #禁止访问 .htxxx 文件
  44.     #location ~ /\.ht {
  45.     #    deny  all;
  46.     #}
  47. }
复制代码
三、nginx负载均衡

1.配置服务器列表地址

修改配置文件 vim default.conf
注意:我们nginx容器启动时-p 8080:80, 下面8001,8002,8003端口为别对应的三个web容器服务,也需要在启动时映射端口到80端口,比方 -p 8001:80
  1. upstream servercluster
  2. {
  3.     server 127.0.0.1:8001;
  4.     server 127.0.0.1:8002;
  5.     server 127.0.0.1:8003;
  6. }
复制代码
然后需要在 location / {…}中进行配置
  1. location / {
  2.        #root   /usr/share/nginx/html;
  3.        #index  index.html index.htm;
  4.        proxy_pass   http://servercluster;
  5.    }
复制代码
2.多集群计谋

轮询默认方式weight权重方式ip_hash依据ip分配方式least_conn最少连接方式fair(第三方)响应时间方式url_hash(第三方)依据url分配方式 注意:在没有配置情况下默认轮询计谋
2.1 权重配置

比方:
  1. #权重越大,命中概率更高 weight,可按照服务器资源来分配
  2. upstream servercluster
  3. {
  4.     server 127.0.0.1:8001  weight=5;
  5.     server 127.0.0.1:8002  weight=3;
  6.     server 127.0.0.1:8003  weight=2;
  7. }
复制代码
2.2 ip_hash

指定负载均衡按照基于客户端IP的分配方式,这个方法确保了雷同的客户端的请求不绝发送到对应的服务器,以保证session会话。这样每个方可都固定访问一个后端服务器,可以解决session不能跨服务器的题目。
比方:
  1. #权重越大,命中概率更高 weight,可按照服务器资源来分配
  2. upstream servercluster
  3. {
  4.     ip_hash; #
  5.     server 127.0.0.1:8001  weight=5;
  6.     server 127.0.0.1:8002  weight=3;
  7.     server 127.0.0.1:8003  weight=2;
  8. }
复制代码
2.3 least_conn

把请求转发给链接数较少的后端服务器。轮询算法是把请求平均的转发给各个后端,使它们的负载大致雷同;但是有些请求占用的时间很长会导致其地点的后端负载较高。这种情况下,least_conn这种方式就可以达到更好的负载均衡效果
  1. upstream servercluster
  2. {
  3.     least_conn; #把请求转发给链接数量较少的后端服务器
  4.     server 127.0.0.1:8001  weight=5;
  5.     server 127.0.0.1:8002  weight=3;
  6.     server 127.0.0.1:8003  weight=2;
  7. }
复制代码
2.4 fair

按照服务端的响应时间来分配请求,响应时间短的有限分配
  1. upstream servercluster
  2. {
  3.     server 127.0.0.1:8001;  
  4.     server 127.0.0.1:8002;
  5.     server 127.0.0.1:8003;
  6.     fair;  #实现响应时间短的优先分配
  7. }
复制代码
2.5 url_hash

按照访问url的hash结果来分配请求,使用每个url定向到同一个后端服务器,要共同缓存命中来使用。同一个资源多次请求,可能会达到不同的服务器上,导致不须要的多次下载,缓存命中率不高,以及一些资源时间的浪费。而使用url_hash可以使用同一个url(也就是同一个资源请求)会到达同一台服务器,一旦缓存了资源,再次收到请求,就可以从缓存中获取
  1. upstream servercluster
  2. {
  3.     hash  $request_url
  4.     server 127.0.0.1:8001;  
  5.     server 127.0.0.1:8002;
  6.     server 127.0.0.1:8003;
  7. }
复制代码
3.nginx缓存配置

通过命令进入到nginx容器中,docker exec -it mynginx bash。
在 /etc/nginx文件夹下建立一个data文件夹用于做nginx缓存。
然后再本地关在文件的主配置文件配置缓存目录经
proxy_cache_path /etc/nginx/data levels=1:2
keys_zone=web_cache:50m inactive=1m max_size=1g
levels:表示有两层文件夹
keys_zone:之情缓存key和缓存50m
max_size:缓存最大1g

然后还需要配置default.conf 开启反向代理数据
proxy_store off; #反向代理数据
proxy_redirect off;
proxy_set_header X-Forwarded-For
$proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://servercluster;
proxy_cache web_cache;
proxy_cache_valid 200 304 2m; #响应200 304 进行缓存
proxy_cache_key                                    s                         c                         h                         e                         m                         e                              scheme                  schemeproxy_host$request_uri; #使用当前url地址作为当前缓存key

注意:修改任何配置文件后都需要重启nginx容器 docker restart mynginx
终极出现文件

四 nginx路由规则

1.匹配格式

这个"/" 表示的是匹配路由规则进行路由转发的。

我们可以在里面写过个location进行路由匹配:
符号规则=开头表示精准匹配~巨细写敏感~*忽略巨细写^~只需匹配url开头@界说一个定名的location,在内部定向时使用 location [ = | ~* | ^~ ] /url/ {…}
location @name {…}
规则使用匹配方式如下:

deny,设置禁止访问的IP
  1. #禁止IP:192.168.1.1访问
  2. location / {
  3.     deny   192.168.1.1;
  4.    }   
复制代码
  1. #禁止所有IP访问
  2. location / {
  3.     deny   all;
  4. }
复制代码
allow,设置答应访问的IP
  1. #只允许IP:192.168.1.1访问
  2. location / {
  3.    allow  192.168.1.1;
  4. }
复制代码
  1. #允许所有IP访问
  2. location / {
  3. allow   all;
  4. }
复制代码
deny和allow的优先级
nginx的权限指令是从上往下执行的,在同一个块下deny和allow指令同时存在时,谁先匹配谁就会起作用,反面的权限指令就不会执行了。如下图,假如 “deny 111.111.111.111” 触发了,那它反面的两条都不会触发。
  1. location / {
  2.    deny 192.168.1.1;
  3.     allow 192.168.1.2;
  4.      deny 192.168.1.3;
  5. }
复制代码
其实他们的关系就像 “if…else if…else if”,谁先触发,谁起作用。
  1. if (deny 192.168.1.1) {...}
  2. else if (allow 192.168.1.2) {...}
  3. else if (deny 192.168.1.3) {...}
复制代码
2.location匹配优先级

在配置中需要注意的一点就是location的匹配规则和优先级


  • = 开头表示精确匹配
  • ^~ 开头表示url以某个通例字符串开头,不是正则匹配;
  • ~ 开头表示区分巨细写的正则匹配
  • ~* 开头表示不区分巨细的正则匹配
  • / 通用匹配,假如没有其他匹配,任何请求都会匹配到;
3.location的匹配流程

1.、判断是否精准匹配,假如匹配,直接返回结果并结束搜索匹配过程
2.、判断是否普通匹配,假如匹配,看是否包罗^~前缀,包罗则返回,否则记录匹配结果location时返回或记录最长匹配的那个
3.、判断是否正则匹配,按配置文件里的正则表达式的顺序,由上到下开始匹配,一旦匹配结果成功,并结束搜索匹配过程.
4.、假如正则匹配没有匹配到结果,则返回步骤2记录的匹配结果
五、 nginx页面拦截

在请求通过nginx的时候,在针对某些场景的使用做特殊处理,比如错误页面,返回指定错误页,比方:

当前默认是在无法响应对应请求的情况下,默认在/usr/share/nginx/html文件下找到50x.html文件,返回页面50x.html


既然是可以配置,我们也可以将自界说的文件复制到对应的目录下面在进行配置。
使用docker cp /url/xxx.html 容器名:ngnix docker中的目标文件下,在修改配置成对应的文件名称
六、 nginx动静分离

对于前端的项目:可以是一个静态服务器或资源池; --可以吧各种静态文件都匹配到nginx中,可以直接请求nginx可以响应不同页面
对于后端项目:做反向代理;
动静分离:需要动态的时候,就做转发请求,需要静态的时候,就直接返回静态页面(直接响应我们的结果)
需求场景:在客户端发起请求时,nginx会转发到服务器服务器然后返回一个静态文件,假如反复请求雷同静态文件都需要去转发到服务器,就会增加开销,性能低落,我们就可以将静态文件报错到nginx中,下次请求就直接返回。
基于.net6解决方式:
1.需要写一个生成静态文件的中间件,保存到指定目录,在项目通过docker启动时挂载到宿主机文件夹下
  1. app.UseStaticPage("/app/data/staticfile", true, true);
复制代码
  1.     /// <summary>
  2.     /// Middleware
  3.     /// </summary>
  4.     public class StaticPageMiddleware
  5.     {
  6.         private readonly RequestDelegate _next;
  7.         private string _directoryPath = null;
  8.         private bool _supportDelete = false;
  9.         private bool _supportWarmup = false;
  10.         public StaticPageMiddleware(RequestDelegate next, string directoryPath, bool supportDelete, bool supportWarmup)
  11.         {
  12.             this._next = next;
  13.             this._directoryPath = directoryPath;
  14.             this._supportDelete = supportDelete;
  15.             this._supportWarmup = supportWarmup;
  16.         }
  17.         /// <summary>
  18.         /// 任意HTTP请求,都要经过这个方法
  19.         ///
  20.         /// 如何抓到响应,并保存成HTML静态页
  21.         /// </summary>
  22.         /// <param name="context"></param>
  23.         /// <returns></returns>
  24.         public async Task InvokeAsync(HttpContext context)
  25.         {
  26.             if (context.Request.Path.Value!.StartsWith("/item/"))//规则支持自定义
  27.             {
  28.                 Console.WriteLine($"This is StaticPageMiddleware InvokeAsync {context.Request.Path.Value}");
  29.                 #region context.Response.Body
  30.                 var originalStream = context.Response.Body;
  31.                 using (var copyStream = new MemoryStream())
  32.                 {
  33.                     context.Response.Body = copyStream;
  34.                     await _next(context);//后续的常规流程,正常请求响应
  35.                     copyStream.Position = 0;
  36.                     var reader = new StreamReader(copyStream);
  37.                     var content = await reader.ReadToEndAsync();
  38.                     string url = context.Request.Path.Value;
  39.                     this.SaveHtml(url, content);
  40.                     copyStream.Position = 0;
  41.                     await copyStream.CopyToAsync(originalStream);
  42.                     context.Response.Body = originalStream;
  43.                 }
  44.                 #endregion
  45.             }
  46.             else
  47.             {
  48.                 await _next(context);
  49.             }
  50.         }
  51.         private void SaveHtml(string url, string html)
  52.         {
  53.             try
  54.             {
  55.                 if (string.IsNullOrWhiteSpace(html))
  56.                     return;
  57.                 if (!url.EndsWith(".html"))
  58.                     return;
  59.                 if (Directory.Exists(_directoryPath) == false)
  60.                     Directory.CreateDirectory(_directoryPath);
  61.                 var totalPath = Path.Combine(_directoryPath, url.Split("/").Last());
  62.                 File.WriteAllText(totalPath, html);//直接覆盖
  63.             }
  64.             catch (Exception ex)
  65.             {
  66.                 Console.WriteLine(ex.Message);
  67.             }
  68.         }
  69.         /// <summary>
  70.         /// 删除某个页面
  71.         /// </summary>
  72.         /// <param name="url"></param>
  73.         /// <param name="index"></param>
  74.         private void DeleteHmtl(string url)
  75.         {
  76.             try
  77.             {
  78.                 if (!url.EndsWith(".html"))
  79.                     return;
  80.                 var totalPath = Path.Combine(_directoryPath, url.Split("/").Last());
  81.                 File.Delete(totalPath);//直接删除
  82.             }
  83.             catch (Exception ex)
  84.             {
  85.                 Console.WriteLine($"Delete {url} 异常,{ex.Message}");
  86.             }
  87.         }
  88.         /// <summary>
  89.         /// 清理文件,支持重试
  90.         /// </summary>
  91.         /// <param name="index">最多重试次数</param>
  92.         private void ClearDirectory(int index)
  93.         {
  94.             if (index > 0)
  95.             {
  96.                 try
  97.                 {
  98.                     var files = Directory.GetFiles(_directoryPath);
  99.                     foreach (var file in files)
  100.                     {
  101.                         File.Delete(file);
  102.                     }
  103.                 }
  104.                 catch (Exception ex)
  105.                 {
  106.                     Console.WriteLine($"ClearDirectory failed {ex.Message}");
  107.                     ClearDirectory(index--);
  108.                 }
  109.             }
  110.         }
  111.     }
  112.     /// <summary>
  113.     /// 扩展中间件
  114.     /// </summary>
  115.     public static class StaticPageMiddlewareExtensions
  116.     {
  117.         /// <summary>
  118.         ///
  119.         /// </summary>
  120.         /// <param name="app"></param>
  121.         /// <param name="directoryPath">文件写入地址,文件夹目录</param>
  122.         /// <param name="supportDelete">是否支持删除</param>
  123.         /// <param name="supportClear">是否支持全量删除</param>
  124.         /// <returns></returns>
  125.         public static IApplicationBuilder UseStaticPage(this IApplicationBuilder app, string directoryPath, bool supportDelete, bool supportClear)
  126.         {
  127.             return app.UseMiddleware<StaticPageMiddleware>(directoryPath, supportDelete, supportClear);
  128.         }
  129.     }
复制代码
2.nginx也需要通过挂载将项目挂载在宿主机的静态文件也挂载到nginx的docker容器中,然后通过修改配置来指定对应的静态文件

OK!!!!!!!!!!!!!
总结

nginx重要的就是一个配置,如有增补大概有差异的地方,贫苦再评论下面指出,共勉!!!!!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

种地

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表