在Eureka集群中使用Zuul
最近将公司的一些服务迁移到spring cloud了,感觉zuul智能路由的功能非常好用,比以前手动在nginx中添加localtion,upstream方便多了,但是服务域名的80端口被nginx占用,所以就采用了nginx+zuul的模式。
废话不说直接上配置,在nginx.conf中添加:
注意“{}”中的信息请填写自己的
server {
listen 80;
server_name {domain};
rewrite ^/a/b/(.*)$ /server1/a/b/$1;
rewrite ^/c/(.*)$ /server2/c/$1;
location /server1 {
proxy_pass http://xx.xx.xx.xxx:8888;
proxy_set_header host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header referer "-";
proxy_redirect default;
}
location /server2 {
proxy_pass http://xx.xx.xx.xxx:8888;
proxy_set_header host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header referer "-";
proxy_redirect default;
}
}
1. server1,server2为服务名,/a/b为server1的context,/c是server2的context
2. http://xx.xx.xx.xxx:8888 是zuul的服务地址
3. rewrite ^/a/b/(.*)$ /a/b/brand/$1; $1表示的是rewrite正则中()中的内容
因为zuul的默认是按 server name 将请求路由的,所以在nginx使用rewrite的方法将请转发到zuul。
https://blog.****.net/mrspirit/article/details/80483667
在Eureka集群中使用Zuul
在Spring Cloud中集群中使用Zuul网关,那么Zuul也是集群的一部分,所以它也应该是一个Eureka项目,如图所示,我们搭建一个最简单的集群,通过网关来分发浏览器发起的请求。
依旧是从Spring Cloud服务管理框架Eureka简单示例(三)这篇博客底部拿到我们的源码,这三个项目对应我们架构图中底部的三个项目,可以启动三个项目的*App启动类,测试项目是否能够正常使用。
底层请求转发的方式:httpClient与okhttp
微服务分布式架构的出现,让http请求成为RPC(Remote Procedure Call,远程过程调用)的首选方式,虽然java平台本身提供了HttpURLConnection来作为http通讯,但是其本身api有限,功能不够强大,所以才有了一系列的http请求工具库出现,这里主要Zuul支持的三种http请求方式:
httpClient:由Apache提供,来作为标准开源http请求客户端,提供了丰富的api,以及强大的功能库,已经是java平台中默认的http请求客户端。在我们的网关中默认就是用了httpClient。
okhttp:由square公司开发,主要目标是高效,专注于提供网络连接效率。它能实现同一ip和端口的请求重用一个socket,这种方式能大大降低网络连接的时间,和每次请求都建立socket,再断开socket的方式相比,降低了服务器服务器的压力。提供对http(http/2)、https以及SPDY的支持。
RestClient:过去zuul使用的分布式rest风格客户端,它基于Ribbon,不过现在已经废弃了。
切换到okhttp或者RestClient,只需要分别设置ribbon.okhttp.enabled=true或者设置ribbon.restclient.enabled=true。
ribbon:
httpclient:
enabled: false
okhttp:
enabled: true
# restclient:
# enabled: true
另外,如果引用的是okhttp,还需要加入依赖:
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</dependency>
运行结果是一致的,我这里就不贴出具体结果了。
路由配置
我们将按照下面的架构来创建项目演示zuul的使用,“网关服务”和“服务提供者”都是简单的Spring Boot项目,“网关服务”通过把用户在浏览器端的请求转发到“服务提供者”来实现路由的功能。
Zuul客户端也注册到了Eureka Server上
https://www.colabug.com/132553.html
这种情况下,Zuul的高可用非常简单,只需将多个Zuul节点注册到Eureka Server上,就可实现Zuul的高可用。此时,Zuul的高可用与其他微服务的高可用没什么区别。
图8-7 Zuul高可用架构图
如图8-7,当Zuul客户端也注册到Eureka Server上时,只需部署多个Zuul节点即可实现其高可用。Zuul客户端会自动从Eureka Server中查询Zuul Server的列表,并使用Ribbon负载均衡地请求Zuul集群。
这种场景一般用于 Sidecar 。
Zuul客户端未注册到Eureka Server上
现实中,这种场景往往更常见,例如,Zuul客户端是一个手机APP——我们不可能让所有的手机终端都注册到Eureka Server上。这种情况下,我们可借助一个额外的负载均衡器来实现Zuul的高可用,例如Nginx、HAProxy、F5等。
图8-8 Zuul高可用架构图
如图8-8,Zuul客户端将请求发送到负载均衡器,负载均衡器将请求转发到其代理的其中一个Zuul节点。这样,就可以实现Zuul的高可用。
节选自《SPRING CLOUD与DOCKER微服务架构实战》8.10节
我们先回顾zuul的生命周期:
http请求首先进入“pre”过滤器,实现身份认证、调试信息等;之后进入“routing”过滤器,将我们的请求转发到微服务中心,并获取响应;接着进入“post”过滤器,对响应的内容进行修饰;最后把响应返回给请求方。
过滤器优先级
如图所示,数字越小,执行的优先级就越高:
图表展示出来就是:
过滤器 | order | 描述 | 类型 |
---|---|---|---|
ServletDetectionFilter | -3 | 检测请求是用 DispatcherServlet还是 ZuulServlet | pre |
Servlet30WrapperFilter | -2 | 在Servlet 3.0 下,包装 requests | pre |
FormBodyWrapperFilter | -1 | 解析表单数据 | pre |
SendErrorFilter | 0 | 如果中途出现错误 | error |
DebugFilter | 1 | 设置请求过程是否开启debug | pre |
PreDecorationFilter | 5 | 根据uri决定调用哪一个route过滤器 | pre |
RibbonRoutingFilter | 10 |
如果写配置的时候用ServiceId则用这个route过滤器,该过滤器可以用Ribbon 做负载均衡,用hystrix做熔断 |
route |
SimpleHostRoutingFilter | 100 | 如果写配置的时候用url则用这个route过滤 | route |
SendForwardFilter | 500 | 用RequestDispatcher请求转发 | route |
SendResponseFilter | 1000 | 用RequestDispatcher请求转发 | post |
为了能够更清晰地知道底层是怎么完成这一系列流程的,我们通过编写一个自定义的过滤器来测试。从我们上一篇博客Spring Cloud集群中使用Zuul(十七) 底部拿到源码。
依次运行四个项目的*App启动类,启动四个项目。
在eureka-zuul网关项目中,在com.init.springCloud包下创建filter包,新建SelfDefineFilter类,去继承Zuul框架的ZuulFilter类,实现内部方法。在图上的Route阶段,三种路由方式都继承了这个ZuulFilter:
--------------------- 本文来自 MrSpirit 的**** 博客 ,全文地址请点击:https://blog.****.net/mrspirit/article/details/80533995?utm_source=copy
Spring Cloud系列:
Spring Cloud服务管理框架Eureka简单示例(三)
Spring Cloud服务管理框架Eureka项目集群(四)
Spring Cloud整合RabbitMQ或Kafka消息驱动(二十二)