SpringCloud微服务注册调用入门-路由网关

xiaoxiao2021-02-28  28

1 . 路由网关的介绍

    路由网关(Zuul)的主要功能是路由转发和过滤器 . 路由功能是微服务的一部分 , 比如/service/user转发到到用户服务 , /service/shop转发到到商店服务等 .  zuul默认和Ribbon结合实现了负载均衡的功能

2 . 路由实现

2.1 与之前类似 , 新建模块zuul , 引入路由依赖

<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> <version>1.4.4.RELEASE</version> </dependency>

2.2 在其启动applicaton类加上注解@EnableZuulProxy,开启zuul的功能

@EnableZuulProxy @EnableEurekaClient @SpringBootApplication public class ZuulApplication { public static void main(String[] args) { SpringApplication.run(ZuulApplication.class, args); } }

2.3 yml配置文件 , 配置路由路径

spring: application: name: szuul server: port: 8950 eureka: client: serviceUrl: defaultZone: http://localhost:9999/eureka/ zuul: routes: api-a: path: /service-a/** serviceId: client-ribbon # 表示/service-a/路径下的请求分发到client-ribbon服务 api-b: path: /service-b/** serviceId: client-feign # 表示/service-b/路径下的请求分发到client-feign服务

2.4 结果测试

    依次启动eurekraserver , service-hello , client-ribbon , client-feign , zuul 6个模块 , 访问网址 http://localhost:8950/service-a/hello?id=123 , http://localhost:8950/service-b/hello?id=123 , 可以看到执行结果(因为我们未启动service-hello , 由于负载均衡的请求分发 , 所以正常会出现交替出现一次成功一次失败的情况) , 能够访问成功 . 

    接下来 , 我们停掉client-ribbon , 再访问 http://localhost:8950/service-a/hello?id=123 , 页面就无法访问了 , 而 http://localhost:8950/service-b/hello?id=123 不受影响 , 这说明路由起到了作用  , 以/service-a/ 开头的请求都转发给client-ribbon服务 , 以/service-b/开头的请求都转发给client-feign服务 . 

3 . 服务过滤

zuul不仅只是路由,并且还能过滤,做一些安全验证 . 为了演示 , 接下来我们继续改造工程

3.1 增加自定义过滤器 继承 ZuulFilter

package com.xbz.zuul.filter; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; @Component public class MyZuulFilter extends ZuulFilter { /** * 返回过滤器类型 * @return * pre:可以在请求被路由之前调用 * routing:在路由请求时候被调用 * post:在routing和error过滤器之后被调用 * error:处理请求时发生错误时被调用 */ @Override public String filterType() { return "pre"; } /** * 通过int值来定义过滤器的执行顺序 , 数字越小优先级越高 */ @Override public int filterOrder() { return 0; } /** * 判断过滤器是否执行 , 返回false则不执行该过滤器 */ @Override public boolean shouldFilter() { return true; } /** * 过滤器的具体逻辑 * ctx.setSendZuulResponse(false)令zuul不允许请求, * ctx.setResponseStatusCode(401)设置了其返回的错误码 * ctx.setResponseBody(body)编辑返回body内容 * @return */ @Override public Object run() throws ZuulException { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); System.out.println(String.format("%s >>> %s", request.getMethod(), request.getRequestURL().toString())); Object accessToken = request.getParameter("token"); if (accessToken == null) { System.out.println("error ! no token !"); ctx.setSendZuulResponse(false); ctx.setResponseStatusCode(401); try { ctx.getResponse().getWriter().write("error ! no token !"); } catch (Exception e) { } return null; } System.out.println("~ ok ~"); return null; } }

3.2 启动类中加入MyZuulFilter

package com.xbz.zuul; import com.xbz.zuul.filter.MyZuulFilter; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; import org.springframework.context.annotation.Bean; @EnableZuulProxy @EnableEurekaClient @SpringBootApplication public class ZuulApplication { public static void main(String[] args) { SpringApplication.run(ZuulApplication.class, args); } @Bean public MyZuulFilter getZuulFilter(){ return new MyZuulFilter(); } }

3.3 结果测试

重启zuul模块 , 再次访问 http://localhost:8950/service-a/hello?id=123 , 会看到如下信息

error ! no token !error ! no token !这说明我们配置的过滤器已经生效 , 必须有token参数才可以正常请求 . 访问  http://localhost:8950/service-a/hello?id=123&token=456 , 得到正常结果 hello 123 , service-hello , I am from port:8900
转载请注明原文地址: https://www.6miu.com/read-2249958.html

最新回复(0)