互联网最常见的形式是(互联网常用项目发布方式---灰度发布和网关zuul的简单理解)

网关zuul

zuul 约 等于 一系列过滤器。

四种过滤器

pre:在请求被路由之前调用,可利用这种过滤器 鉴权。选择微服务,记录日志,限流。

route:在将请求路由到微服务调用,用于构建发送给微服务的请求,并用http clinet(或者Ribbon)请求微服务。

post:在调用微服务执行后。可用于添加header,记录日志,将响应发给客户端。

error:在其他阶段发生错误是,走此过滤器。

四种过滤器执行顺序:

灰度发布:

① 用户通过zuul网关进行服务调用;此时进行灰度发布,利用ribbon和eureka的meta进行动态路由

使用eureka的元数据信息,再配上ribbon的路由功能,就可以在api-gateway实现很多功能,比如灰度测试、生产调试等等。下面介绍一下,怎么使用jmnarloch大神提供的ribbon-discovery-filter-spring-cloud-starter,利用简单的几行代码搞定这一切




添加pom依赖

<dependency> <groupId>io.jmnarloch</groupId> <artifactId>ribbon-discovery-filter-spring-cloud-starter</artifactId> <version>2.1.0</version> </dependency>

路由

@Component public class DynamicRoutesFilter extends ZuulFilter { private static final Logger LOGGER = LoggerFactory.getLogger(DynamicRoutesFilter.class); @Override public String filterType() { return FilterConstants.ROUTE_TYPE; //使用路由 //return "pre"; } @Override public int filterOrder() { return 0; } @Override public boolean shouldFilter() { return true; } @Override public Object run() throws ZuulException{ requestContext currentContext = RequestContext.getCurrentContext(); HttpServletRequest request = currentContext.getRequest(); int userId = Integer.parseInt(request.getHeader("userId")); // 根据用户id 查 规则 查库 v1,meata // 含义是:查库(动态的)得到发布的规则,如果是v1,matedata的规则也是v1(也可以是在请求头header的属性中配置) // 匹配上了才走下面的逻辑 // 金丝雀 if (userId == 1){ RibbonFilterContextHolder.getCurrentContext().add("version","v1"); // 普通用户 }else if (userId == 2){ RibbonFilterContextHolder.getCurrentContext().add("version","v2"); } return null; } }


② 新发布服务不经过网关,是内部服务间的调用;利用 @Aspect 切面和自定义 ribbon 的规则 IRule 来实现

互联网创业形式包括哪些新闻

api-passenger调用sms服务的时候,通过rule规则,实现特定用户调用某个或某些指定的sms服务

流程:api-passenger的testCall()方法调用sms-test()方法,用postman在request的header中设置属性,userId=1

@Aspect @Component public class RequestAspect { @Pointcut("execution(* com.mashibing.apipassenger.controller..*Controller*.*(..))") private void anyMehtod(){} @Before(value = "anyMehtod()") public void before(JoinPoint joinPoint){ HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest(); String version = request.getHeader("version"); // 灰度规则 匹配的地方 查db,redis ==== if (version.trim().equals("v2")){ RibbonFilterContextHolder.getCurrentContext().add("version","v2"); } } }

被拦截的方法

@RestController @RequestMapping("/test") public class TestCallServiceSmsController { @Autowired private RestTemplate restTemplate; @GetMapping("/call") public String testCall(){ return restTemplate.getForObject("http://service-sms/test/sms-test",String.class); } }

自定义ribbon规则(根据用户信息,选择不同的服务进行分发)。拿到 自定义元数据 metadata


public class MsbRandomRule extends AbstractLoadBalancerRule{ public Server choose(ILoadBalancer lb, Object key) { // 。。。。省略 System.out.println("MsbRandomRule 自定义rule"); return server; } @Override public Server choose(Object key){ return choose(getLoadBalancer(), key); } @Override public void initWithNiwsConfig(IClientConfig clientConfig){ } }


/** * 该类不应该在主应用程序的扫描之下,需要修改启动类的扫描配置。否则将被所有的Ribbon client共享, * 比如此例中:ribbonRule 对象 会共享。 * 在主类上进行忽略 * @ComponentScan( * excludeFilters = { * @ComponentScan.Filter(type = FilterType.ANNOTATION,value = ExcudeRibbonConfig.class) * }) */ @ExcudeRibbonConfig //自定义注解,功能同@Configuration public class RibbonConfiguration { @Bean public IRule ribbonRule() { return new MsbRandomRule(); } }



token通过网关zuul,不往后传的问题

cookie或者token都是做身份识别或鉴权用的,由各个服务往上提取到网关,由网关来做,那么就不应该再将cookie或者token下发下去了。也可以配置,让cookie可以下发

zuul:

#以下配置,表示忽略下面的值向微服务传播,以下配置为空表示:所有请求头都透传到后面微服务。

sensitive-headers:

您可以还会对下面的文章感兴趣

使用微信扫描二维码后

点击右上角发送给好友