大家好,又见面了,我是你们的朋友全栈君。
1.微服务架构所面临的问题?
1)针对某个功能,客户端在微服务架构的情况下需要请求多个模块接口
2)针对于身份认证、日志、流量控制等公共模块每个微服务都需要做一遍,不利于业务与非业务的拆分
针对于这些问题,Zuul可完美解决,我们可用Zuul做:
1)客户端只需要知道网关而不需要知道具体模块的地址,所有服务由网关对外提供
2)身份认证类的东西单独抽象出来,业务模块只做业务
2.Zuul网关构建
1)在SpringBoot工程 part-1-website 中添加依赖,如下
代码语言:javascript复制 <!-- spring-cloud-starter-hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>Dalston.SR1</version>
<relativePath />
</parent>
2)在Application上添加@EnableZuulProxy注解,开启Zuul网关服务
代码语言:javascript复制@EnableZuulProxy
public class WebsiteApp {
}
3)设置该工程应用名称、端口号等信息
代码语言:javascript复制# 应用名称
spring:
application:
name: part-1-website
#端口
server:
port: 1102
以上即成功构建应用,以下为请求路由方式
3.Zuul的几种请求路由方式
准备工作:
1)启动一个高可用的Eureka-server
2)创建一个服务应用,以对外提供接口服务
3)复制一份该服务端服务,除了端口号不一致其他都保持一致,尤其spring.application.name要保持一致,用于验证在外部请求到达时是否负载均衡
具体可参考笔者另一篇文章 Ribbon负载均衡的使用方式与配置方式详解_恐龙弟旺仔的博客-CSDN博客_ribbon设置负载方式
笔者在本示例中服务应用名称设置为 part-1-sms-interface ,全部四个应用启动后,访问eureka可看到
以上:PART-1-EUREKA即为高可用eureka-server;PART-1-SMS-INTERFACE即为对外服务应用,提供/sms/test服务
1)传统路由
* 单实例配置(通过zuul.routes.<route>.path和zuul.routes.<route>.url参数对的方式来配置)
在application.properties文件中添加路由规则即可
代码语言:javascript复制#route rule
zuul.routes.part-1-website.path=/part-1-website/**
zuul.routes.part-1-website.url=http://localhost:1109/
注意:以上规则即说明,对当前website应用的所有以 /part-1-website开始的请求路径全部转发到http://localhost:1109上;
如果是请求localhost:1102/part-1-website/sms/test即会转发到localhost:1109/sms/test上,即实现对PART-1-SMS-INTERFACE的服务访问
* 多实例配置(通过zuul.routes.<route>.path和zuul.routes.<route>.serviceId参数对的方式来配置)
在application.properties文件中添加如下路由规则即可
代码语言:javascript复制zuul.routes.part-1-website.path=/part-1-website/**
zuul.routes.part-1-website.serviceId=website
website.ribbon.listOfServers=http://localhost:1108/,http://localhost:1109/
注意:与单实例不同就是:通过serviceId和listOfServers来确定path和url的对应关系;
website读者可自定义,只要保持与listOfServers保持一致即可,servers值即PART-1-SMS-INTERFACE服务对应的应用IP:端口
2)服务路由配置
通过Zuul和Eureka的整合,实现对服务实例的自动化维护
在这种情况下,我们不需要像传统路由那样为serviceId指定具体的服务实例地址,只需要将path和serviceId对应上
注意:实现这种方式,需要引入eureka依赖,并将zuul实例注册到eureka中
在application.properties文件中添加如下路由规则
代码语言:javascript复制zuul.routes.part-1-website.path=/part-1-website/**
zuul.routes.part-1-website.service-id=part-1-sms-interface
eureka.client.service-url.defaultZone=http://eureka1:1001/eureka/
注意:service-id即为要调用的服务名称;需要将本应用注册到eureka
4.过滤器
过滤负责对请求的处理过程进行干预,是实现请求校验、服务聚合等功能的基础。
Zuul的过滤器使用方式如下:
1)创建一个类,继承com.netflix.zuul.ZuulFilter
代码语言:javascript复制public class AccessFilter extends ZuulFilter{
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext context = RequestContext.getCurrentContext();
HttpServletRequest request = context.getRequest();
//也可获取其他参数,如response、
String token = request.getParameter("accessToken");
if(StringUtils.isEmpty(token)){
context.setSendZuulResponse(false);
context.setResponseStatusCode(401);
context.setResponseBody("has no accessToken");
}
return null;
}
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 0;
}
}
注意:需实现ZuulFilter的abstract方法;
shouldFilter:true表示需要过滤;false表示不需要
filterType:
* pre 请求被路由之前被调用(一般做一些前置加工)
* route 在路由请求时调用(将外部请求转发到具体的服务实例上)
* post 路由请求返回时调用(包装加工返回信息)
* error 处理请求发生错误时调用
filterOrder:通过数字来表示filter的执行顺序
run:做真正的逻辑处理
2)在Application下创建@Bean,将此Filter作为一个bean注入
代码语言:javascript复制 @Bean
public AccessFilter accessFilter(){
return new AccessFilter();
}
3)重启应用后,发出请求,如果request中没有添加AccessToken,则会收到报错,说明Filter生效
参考:Spring Cloud微服务实战
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/170620.html原文链接:https://javaforall.cn