场景
-
大量用户请求的情况下,短时间并发很高 # 思路
-
nginx 通过反向代理 做负载均衡 # 基础概念 ### 反向代理(Reverse Proxy)
-
用途
- 隐藏服务器的真实IP
- 负载均衡
- 通过缓存加速访问资源
- 提供安全保障 ### 负载均衡
-
实际生产环境中,反向代理服务器代理的目标服务器可能不止一个。比如开发好的某个应用部署在一台Tomcat服务器上,而Tomcat的并发上限不优化情况下,默认只有两百左右,这时候为了解决高并发的问题,就只能选择更替服务器或者搭建多台服务器通过反向代理与负载均衡的技术解决高并发问题。
负载均衡(Load Balance)
是由多台服务器以对称的方式组成一个服务器集群,每台服务器都具有等价的地位,都可以单独对外提供服务而无需其他服务器的辅助。经过某种负载分管技术,将外部发送来的中央请求均匀分配到对称结构中的某一台服务器上。 ### nginx反向代理与负载均衡
-
nginx是由lgor Sysoev(伊戈尔 赛索耶夫)为俄罗斯访问量第二的https://www.rambler.ru/ 站点开发的。nginx是一个高性能的HTTP和反向代理服务器,可以扛得住5W左右的并发。Nginx一方面可以做反向代理服务器,另外一方面还可以做静态资源服务器。
-
nginx 官网地址 http://nginx.org/ # 搭建 ### 环境
-
二台服务器 (都为ubuntu)
- 家里ubuntu 8核心 24G
- 安装nginx
- 启动一个项目
- 本机启动一个项目 ### 安装nginx (如果已经安装,可以略过)
sudo apt updatesudo apt install nginx
- 家里ubuntu 8核心 24G
-
安装完成,nginx将会自动被启动。可以运行如下命令来验证它
sudo systemctl status nginx
- 输出类似下面这样:
● nginx.service - A high performance web server and a reverse proxy server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled) Active: active (running) since Sat 2020-05-02 20:25:43 UTC; 13s ago...
- 测试安装
- 想要测试你的新 Nginx 安装,在你的浏览器中打开http://YOUR_IP,你应该可以看到默认的 Nginx 加载页面,像下面这样:
nginx配置文件结构和最佳实践
- 所有的 Nginx 配置文件都在/etc/nginx/目录下。
- 主要的 Nginx 配置文件是/etc/nginx/nginx.conf。
- 为每个域名创建一个独立的配置文件,便于维护服务器。你可以按照需要定义任意多的 block 文件。
- Nginx 服务器配置文件被储存在/etc/nginx/sites-available目录下。在/etc/nginx/sites-enabled目录下的配置文件都将被 Nginx 使用。
- 最佳推荐是使用标准的命名方式。例如,如果你的域名是mydomain.com,那么配置文件应该被命名为/etc/nginx/sites-available/mydomain.com.conf
- 如果你在域名服务器配置块中有可重用的配置段,把这些配置段摘出来,做成一小段可重用的配置。
- Nginx 日志文件(access.log 和 error.log)定位在/var/log/nginx/目录下。推荐为每个服务器配置块,配置一个不同的access和error。
- 你可以将你的网站根目录设置在任何你想要的地方。最常用的网站根目录位置包括:
- /home/
/ - /var/www/
- /var/www/html/
- /opt/
- /home/
配置nginx
-
在/etc/nginx/conf.d
下新建 msb-test.conf文件sudo touch msg-test.conf
-
直接编辑
sudo vim /etc/nginx/nginx.conf
-
配置注意: upstream 的名称不能是带 (下划线),否则会出现400
-
权重分配方式
- 轮询(默认)
- 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
- weight
- 指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
- ip_hash
- 每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
- fair(第三方)
- 按后端服务器的响应时间来分配请求,响应时间短的优先分配。
- url_hash(第三方)
- 按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。
- 轮询(默认)
-
upstream 更多用法,参数配置参考官网 https://nginx.org/en/docs/http/ngx_http_upstream_module.html
- 每个设备的状态设置为: 1.down 表示单前的server暂时不参与负载 2.weight 默认为1.weight越大,负载的权重就越大。 3.max_fails :允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream 模块定义的错误 4.fail_timeout:max_fails次失败后,暂停的时间。 5.backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。
测试
- 启动
- 进入项目所在目录 执行
nohup java -jar back-0.0.1-SNAPSHOT.jar >1.log 2>&1 &
启动 tail -f 1.log
查看日志
- 进入项目所在目录 执行
- 通过本地访问 http://localhost:9898 对应接口 测试后台是否有负载 均匀分配请求
- 测试发现 根据配置不同,请求不同的后台地址
其他方案
-
spring-boot
- tomcat 处理请求时的线程池最大线程数 调整
- server.tomcat.max-threads=400
- tomcat 处理请求时的线程池最大核心数 (一般是核心数+1)
- server.tomcat.min-spare-threads=9
- 增加数据库连接数
spring: datasource: hikari: connection-test-query: SELECT 1 FROM DUAL connection-timeout: 600000 maximum-pool-size: 500 max-lifetime: 1800000 minimum-idle: 20 validation-timeout: 3000 idle-timeout: 60000
- tomcat 处理请求时的线程池最大线程数 调整
-
使用current-limiting对接口限流
- 在pom.xml 中添加依赖
cn.yueshutong spring-boot-starter-current-limiting 0.0.8.RELEASE - 在application.yml中添加以下代码
current: limiting: #开启全局限流 enabled: false #开启注解限流,可使注解失效 part-enabled: true #每秒并发量 这里的qps是全局限流开启的时候的值,如果使用注解在注解里设置QPS值 qps: 100 #开启快速失败,可切换为阻塞 fail-fast: true #系统启动保护时间为0 initial-delay: 1
- 在需要的限流的接口上添加注解
@RequestMapping(value = "/login",method = RequestMethod.POST) @CurrentLimiter(QPS=5) public ResponseModel loginUser(@RequestBody JSONObject account)
- 新建MyCurrentLimitHandler.java文件,自定义被拦截时的返回信息
import cn.yueshutong.springbootstartercurrentlimiting.annotation.CurrentLimiter; import cn.yueshutong.springbootstartercurrentlimiting.handler.CurrentAspectHandler; import com.program.facesigninsystem.entity.ResponseModel; import org.aspectj.lang.ProceedingJoinPoint; import org.springframework.stereotype.Component; @Component public class MyCurrentLimitHandler implements CurrentAspectHandler { @Override public ResponseModel around(ProceedingJoinPoint pjp, CurrentLimiter rateLimiter) { return new ResponseModel(500,"系统繁忙,请稍后重试"); } }
-
Kubernetes (k8s负载)
-
官网 https://kubernetes.io/zh-cn/ # 参考
文章评论