服务器之家

服务器之家 > 正文

SpringCloud如何实现Zuul集群(负载均衡)

时间:2021-09-26 10:27     来源/作者:王小白_Ada

前言:

在微服务架构中,有一个组件可以说是必不可少的,那就是微服务网关,微服务网关处理了负载均衡,缓存,路由,访问控制,服务代理,监控,日志等。API网关在微服务架构中正是以微服务网关的身份存在。

一般在微服务架构中,网关都是部署多个服务的,以实现负载均衡和保证高可用。

一、使用 Nginx+Zuul 实现网关集群

1.互联网公司中网关都是集群 搭建集群: Nginx+Zuul 一主一备,或者轮询多个。

2.在微服务中,所有服务请求都会统一请求到Zuul网关上。

图示:

SpringCloud如何实现Zuul集群(负载均衡)

过程:客户端发送请求统一到Nginx上,在使用Nginx实现反向代理和负载均衡,采用轮询算法转发到网关上。

1.创建Eurek注册中心、会员服务、订单服务 (略)

搭建Zull集群前,应该对Eureka注册中心,以及创建SpringBoot项目应该有了解,这里就不一 一赘述了。

实际上创建会员服务、订单服务这一步可以省略,因为我们仅仅是为了演示Nginx对Zuul网关的负载均衡效果。

会员服务配置:

过程:客户端发送请求统一到Nginx上,在使用Nginx实现反向代理和负载均衡,采用轮询算法转发到网关上。1.创建Eurek注册中心、会员服务、订单服务 (略)

搭建Zull集群前,应该对Eureka注册中心,以及创建SpringBoot项目应该有了解,这里就不一 一赘述了。实际上创建会员服务、订单服务这一步可以省略,因为我们仅仅是为了演示Nginx对Zuul网关的负载均衡效果。

会员服务配置:

  1. #会员服务
  2. server:
  3. port: 8082
  4. spring:
  5. application:
  6. name: member-service #服务名
  7. #Eureka配置
  8. eureka:
  9. client:
  10. service-url:
  11. defaultZone: http://127.0.0.1:8761/eureka/ #注册中心的地址

订单服务:

  1. #订单服务
  2. server:
  3. port: 8081
  4. spring:
  5. application:
  6. name: order-service #服务名
  7. #Eureka配置
  8. eureka:
  9. client:
  10. service-url:
  11. defaultZone: http://127.0.0.1:8761/eureka/ #注册中心地址

2. 创建Zuul服务

application.yml文件中配置 (Zull的配置生产时一般是放到配置中心中)

  1. #配置Zuul端口
  2. server:
  3. port: 81
  4. spring:
  5. application:
  6. name: zull-gateway-service #服务名
  7. #Eureka配置
  8. eureka:
  9. client:
  10. service-url:
  11. defaultZone: http://127.0.0.1:8761/eureka/ #注册中心地址
  12.  
  13. # 配置网关反向代理,例如访问/api-member/** 直接重定向到member-service服务,实现路由转发,隐藏服务的真实ip(服务都实在内网中)
  14. #zull根据服务名,去Eureka获取服务真实地址,并通过本地转发,而且默认开启Ribbon实现负载均衡
  15. #默认读取Eureka注册列表 默认30秒间隔
  16. zuul:
  17. routes:
  18. api-a: #会员服务网关配置
  19. path: /api-member/** #访问只要是/api-member/ 开头的直接转发到member-service服务
  20. #服务名
  21. serviceId: member-service
  22. api-b: #订单服务网关配置
  23. path: /api-order/**
  24. serviceId: order-service

创建TokenFilet类继承ZuulFilter,在run方法中输入网关的端口,调用服务时方便查看Nginx转发到哪个网关

  1. package com.example.zuul.filter;
  2. import com.netflix.zuul.ZuulFilter;
  3. import com.netflix.zuul.context.RequestContext;
  4. import com.netflix.zuul.exception.ZuulException;
  5. import io.micrometer.core.instrument.util.StringUtils;
  6. import org.springframework.beans.factory.annotation.Value;
  7. import org.springframework.stereotype.Component;
  8. import javax.servlet.http.HttpServletRequest;
  9. @Component
  10. public class TokenFilter extends ZuulFilter {
  11. //统计当前Zuul调用次数
  12. int count = 0;
  13.  
  14. //获取Zuul服务端口号
  15. @Value("${server.port}")
  16. private String prot;
  17.  
  18. /**
  19. * 指定该Filter的类型
  20. * ERROR_TYPE = "error";
  21. * POST_TYPE = "post";
  22. * PRE_TYPE = "pre";
  23. * ROUTE_TYPE = "route";
  24. */
  25. @Override
  26. public String filterType() {
  27. System.out.println("filterType()...");
  28. return "pre";
  29. }
  30. /**
  31. * 指定该Filter执行的顺序(Filter从小到大执行)
  32. * DEBUG_FILTER_ORDER = 1;
  33. * FORM_BODY_WRAPPER_FILTER_ORDER = -1;
  34. * PRE_DECORATION_FILTER_ORDER = 5;
  35. * RIBBON_ROUTING_FILTER_ORDER = 10;
  36. * SEND_ERROR_FILTER_ORDER = 0;
  37. * SEND_FORWARD_FILTER_ORDER = 500;
  38. * SEND_RESPONSE_FILTER_ORDER = 1000;
  39. * SIMPLE_HOST_ROUTING_FILTER_ORDER = 100;
  40. * SERVLET_30_WRAPPER_FILTER_ORDER = -2;
  41. * SERVLET_DETECTION_FILTER_ORDER = -3;
  42. */
  43. @Override
  44. public int filterOrder() {
  45. System.out.println("filterOrder()...");
  46. return 0;
  47. }
  48. /**
  49. * 指定需要执行该Filter的规则
  50. * 返回true则执行run()
  51. * 返回false则不执行run()
  52. */
  53. @Override
  54. public boolean shouldFilter() {
  55. System.out.println("shouldFilter()...");
  56. return true;
  57. }
  58. /**
  59. * 该Filter具体的执行活动
  60. */
  61. @Override
  62. public Object run() throws ZuulException {
  63. // 获取上下文
  64. //RequestContext currentContext = RequestContext.getCurrentContext();
  65. //HttpServletRequest request = currentContext.getRequest();
  66. //获取userToken
  67. // String userToken = request.getParameter("userToken");
  68. //System.out.println("userToken: "+userToken);
  69. //if (StringUtils.isEmpty(userToken)) {
  70. //不会继续执行调用服务接口,网关直接响应给客户端
  71. //currentContext.setSendZuulResponse(false);
  72. //currentContext.setResponseStatusCode(401);
  73. // currentContext.setResponseBody("userToken is Null");
  74. // return null;
  75. // }else if(!userToken.equals("10010")){
  76. // currentContext.setSendZuulResponse(false);
  77. //currentContext.setResponseStatusCode(401);
  78. //currentContext.setResponseBody("userToken is Error");
  79. //return null;
  80. //}
  81. // 否则正常执行业务逻辑,调用服务.....
  82. System.out.println("访问Zuul网关端口为:"+prot +"(total:"+ ( count++) +")");
  83. return null;
  84. }
  85. }

启动两个Zuul服务,端口号分别为81和82

3. 下载Nginx服务器

这里演示使用Windows版本,Linux安装也很简单,后面操作都一样。

windows版下载地址:http://nginx.org/en/download.html

SpringCloud如何实现Zuul集群(负载均衡)

下载好后解压,进入conf目录找到nginx.conf文件打开,配置如下:

  1. #配置上游服务器 集群,默认轮询机制
  2. upstream backServer{
  3. server 127.0.0.1:81;
  4. server 127.0.0.1:82;
  5. # 补充: backup表示从服务器或者叫备用服务器 只有当主服务器(81、82端口)都不能访问时才会访问此(83端口)备用服务器 当主服务器恢复正常后 则访问主服务器
  6. #server 127.0.0.1:83 backup;
  7. }
  8. server {
  9. listen 80;
  10. server_name localhost;
  11. #charset koi8-r;
  12. #access_log logs/host.access.log main;
  13. location / {
  14. ##root html;
  15. #指定上游负载均衡服务器
  16. proxy_pass http://backServer/;
  17. index index.html index.htm;
  18. }
  19. }

双击nginx.exe启动Nginx服务器

二、 测试

浏览器访问http://localhost/api-member

我们可以看到两个网关分别输出了日志,实现了负载均衡

SpringCloud如何实现Zuul集群(负载均衡)

SpringCloud如何实现Zuul集群(负载均衡)

我们看到访问的次数不一样,这其实和使用Google浏览器有关,可以换其他浏览器试试。

三、补充

 

Nginx和网关的区别在什么地方?

1、都可以实现反向代理。

2、都可以实现负载均衡,Nginx是服务端负载均衡,Zuul是本地负载均衡。

Nginx也可以实现网关,为什么不用Nginx实现网关呢?

因为微服务网关是针对整个微服务实现统一的请求拦截,网关基本上都是采用自己熟悉的语言开发的,目的方便易学。

网关的作用:

1、网关对所有服务会话进行拦截

2、网关安全控制、统一异常处理、xxs、sql注入

3、权限控制、黑名单和白名单、性能监控、日志打印等

关于Nginx负载均衡故障转移:

设置备用服务器(主从架构),只有当所有主服务器不可用时才会负载到备服务器,当主服务器恢复正常时则负载到主服务器。

  1. upstream backServer{
  2. server 127.0.0.1:81;
  3. server 127.0.0.1:82;
  4. # 补充: backup表示从服务器或者叫备用服务器 只有当主服务器(81、82端口)都不能访问时才会访问此(83端口)备用服务器 当主服务器恢复正常后 则访问主服务器
  5. server 127.0.0.1:83 backup;
  6. }

设置Nginx转发请求超时时间

  1. upstream backServer{
  2. server 127.0.0.1:81;
  3. server 127.0.0.1:82;
  4. server 127.0.0.1:83 backup;
  5. }
  6.  
  7. location / {
  8. proxy_pass http://backServer/;
  9. proxy_redirect default;
  10. proxy_connect_timeout 1; # 超时1s则转发到其他服务,宕机情况下也适用
  11. proxy_read_timeout 1;
  12. proxy_send_timeout 1;

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

原文链接:https://blog.csdn.net/qq_38252039/article/details/90116113

相关文章

热门资讯

yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
2021年耽改剧名单 2021要播出的59部耽改剧列表
2021年耽改剧名单 2021要播出的59部耽改剧列表 2021-03-05
返回顶部