话不多说,先上图(图是丑陋了点,大家别介意哈),这幅图是我根据公司现有的业务设计出来的一个简单的基于springcloud微服务架构图。
在springcloud微服务体系中,我们一般不对外直接暴露服务层的接口,而是中间通过一层代理进行中转,这层代理的好处一个是对外可以隐藏我们内部具体服务的接口,另一个就是我们非常重要的服务的负载均衡,在上图中客户端的所有请求先经过nginx(Nginx集群)经由nginx代理转发后进入springcloud的zuul(zuul集群)路由网关服务,由zuul再去对应具体的服务;我们的所有服务均统一注册到高可用的服务注册发现(eureka server)集群中。
首先介绍一下zuul的功能:
zuul的主要功能是路由转发和过滤器。路由功能是微服务的一部分,比如/frnt转发到到frnt服务,/portal转发到portal服务。zuul默认和Ribbon结合实现了负载均衡的功能。
好啦,正式开工!
1.首先创建一个项目xx-zuul(名字任意取),引入相关依赖(spring-cloud-starter-netflix-zuul):
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency> <!--eureka client--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> <version>1.4.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
2.打开application-dev.properties并加入以下内容:
#端口 server.port=8763 #实例名 spring.application.name=xx-zuul #注册中心 eureka.server.host=localhost eureka.server.port=8761 eureka.client.service-url.defaultZone=http://${eureka.server.host}:${eureka.server.port}/eureka/ #路由规则配置 #拦截路径 zuul.routes.demo-springboot.path=/demo/** #eureka中注册的实例名 zuul.routes.demo-springboot.serviceId=demo-springboot #实际访问时去除前缀(即:经过zuul转发后会去除掉demo前缀) zuul.routes.demo-springboot.stripPrefix=true #连接超时时间 zuul.host.connect-timeout-millis=15000 zuul.host.socket-timeout-millis=10000 #log level logging.level.root=debug #开启eureka client健康检查 eureka.client.healthcheck=true # 续约到期时间(默认90秒) eureka.instance.lease-expiration-duration-in-seconds=30 # 续约更新时间间隔(默认30秒) eureka.instance.lease-renewal-interval-in-seconds=10
3.开启zuul代理注解@EnableZuulProxy
@EnableZuulProxy @EnableEurekaClient @SpringBootApplication public class Xsignal2ZuulApplication { public static void main(String[] args) { SpringApplication.run(Xsignal2ZuulApplication.class, args); } }
4.最后启动xx-zuul服务,demo-springboot服务,在eureka控制面板查看:
打开浏览器准备访问zuul代理:
看到如图结果表示我们的zuul代理已经生效,成功访问到了demo-springboog项目,庆贺一下吧!
另外,文章开头说道zuul支持过滤功能,即我们可以通过自定义filter继承自ZuulFilter即可:
@Component public class MyFilter extends ZuulFilter { /*filterType:返回一个字符串代表过滤器的类型,在zuul中定义了四种不同生命周期的过滤器类型,具体如下: pre:路由之前 routing:路由之时 post: 路由之后 error:发送错误调用 filterOrder:过滤的顺序 shouldFilter:这里可以写逻辑判断,是否要过滤,本文true,永远过滤。 run:过滤器的具体逻辑。可用很复杂,包括查sql,nosql去判断该请求到底有没有权限访问。 */ private static Logger log = LoggerFactory.getLogger(MyFilter.class); @Override public String filterType() { return FilterConstants.PRE_TYPE; } @Override public int filterOrder() { return 0; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); Object accessToken = request.getParameter("token"); if(accessToken == null) { log.warn("token is empty"); ctx.setSendZuulResponse(false); ctx.setResponseStatusCode(401); try { ctx.getResponse().getWriter().write("token is empty"); }catch (Exception e){} return null; } return null; } }在filter中我们可以自定义需要过滤的请求,拦截非法请求,权限认证,频控,限流等操作!