网关

Starter阿里云镜像

https://start.aliyun.com/

概念

微服务基本模块已经有了-也可以做微服务了。但完成一个复杂的业务-可能需要多个微服务合作来完成-比如下单-需要用户服务-支付服务-地图服务-订单服务。一般是我们对外服务的窗口-进行服务内外隔离。一般微服务都在内网-不做安全验证-

就好像:很多明星-可以独立开演唱会(独立提供服务)。也可以去春晚(微服务群提供服务)。但一台春晚就不能让 观众一个一个调用了。观众要调用-需要检票啥的-检票就类似于网关-进来之后-界面随便看-不会说你 看个小品-还需要再检票。

微服务没有网关-会有下面的问题:

  • 客户端请求多个微服务-增加了客户端复杂性-每个微服务都要做用户认证-限流等-避免和多个微服务打交道的复杂性。
  • 有跨域问题-不在同一个域。
  • 认证复杂-每个服务都要独立认证-服务要求的权限不一致。
  • 难以重构。因为微服务被客户端调用着-重构难以实施。
  • 网关是介于客户端(外部调用方比如app-h5)和微服务的中间层。

    Zuul是Netflix开源的微服务网关-核心是一系列过滤器。这些过滤器可以完成以下功能。

  • 是所有微服务入口-进行分发。
  • 身份认证与安全。识别合法的请求-拦截不合法的请求。
  • 监控。在入口处监控-更全面。
  • 动态路由。动态将请求分发到不同的后端集群。
  • 压力测试。可以逐渐增加对后端服务的流量-进行测试。
  • 负载均衡。也是用ribbon。
  • 限流(望京超市)。比如我每秒只要1000次-10001次就不让访问了。
  • 服务熔断
  • 网关和服务的关系:演员和剧场检票人员的关系。

    zuul默认集成了:ribbon和hystrix。

    启用网关

    新建项目引入依赖

    ``plain org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.cloud spring-cloud-starter-netflix-zuul `

    配置文件

    `plain eureka.client.service-url.defaultZone=http://euk1.com:7001/eureka/spring.application.name=zuulserverserver.port=80 `

    启动类

    `plain @EnableZuulProxy `

    测试访问

    网关会将服务名转换成具体服务的ip和端口-实际进行访问

    `plain http://localhost/consumer/alive `

    负载均衡

    启动两个Consumer

    轮询访问上面地址-会看到返回结果中-端口一直轮询在变。说明负载均衡生效了-默认是轮询

    `plain consumer.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule `

    路由端点

    调试的时候-看网关请求的地址-以及 映射是否正确。网关请求有误时-可以通过此处排查错误。

    配置

    `plain management.endpoints.web.exposure.include=*management.endpoint.health.show-details=alwaysmanagement.endpoint.health.enabled=truemanagement.endpoint.routes.enabled=true `

    配置指定微服务的访问路径

  • 通过服务名配置(虚拟主机名)
  • `sh zuul.routes.consumer=/xxoo/** `

    配置前先访问-然后做对比。

    2.自定义映射

    `plain zuul.routes.xx.path=/xx/**zuul.routes.xx.url=http://mashibing.com `

  • .自定义下的负载均衡
  • `plain zuul.routes.xx.path=/xx/**zuul.routes.xx.service-id=cuidcuid.ribbon.listOfServers=localhost:82,localhost:83ribbon.eureka.enabled=false `

    忽略微服务

    配置

    `plain zuul.ignored-services=user-provider `

    前缀

    `plain zuul.prefix=/api/v1 `

    带上前缀请求

    `plain zuul.strip-prefix=false `

    高可用

    Nginx + Keepalive

    敏感Header

    测试点:

    停止一个api-driver。访问:yapi:网关token-看返回。

    初始请求。返回值中token为msb cookie

    加上下面配置

    敏感的header不会传播到下游去-也就是说此处的token不会传播的其它的微服务中去。

    `sh zuul: #一下配置-表示忽略下面的值向微服务传播-以下配置为空表示:所有请求头都透传到后面微服务。 sensitive-headers: token `

    访问。网关token为null。

    ---

    上面是网关的路由。

    过滤器

    Zuul的大部分功能都是有过滤器实现的。

    4种过滤器

    `sh PRE: 在请求被路由之前调用-可利用这种过滤器实现身份验证。选择微服务-记录日志。ROUTING:在将请求路由到微服务调用-用于构建发送给微服务的请求-并用http clinet(或者ribbon)请求微服务。POST:在调用微服务执行后。可用于添加header-记录日志-将响应发给客户端。ERROR:在其他阶段发生错误是-走此过滤器。 `

    自定义过滤器

    `sh PreFilter看代码-注意下面4点。filterType:pre-routing,post,errorfilterOrder:执行顺序-在谁前-在谁后-可以+1--1shouldFilter:此过滤器是否执行-true false-可以写过滤器是否执行的判断条件。run:具体执行逻辑。 `

    访问:yapi中 网关token

    `sh pre来源uri:/api-driver/test/tokenpre拦截pre 业务逻辑 token:msb coolie `

    说一下AuthFilter。利用filter实现了 鉴权。看代码。(实际用jwt)

    测试一下-

    `sh // 测试路径// if(uri.contains("api-driver")) {// return true;// } `

    接口容错

    `sh @Componentpublic class MsbFallback implements FallbackProvider{ /** * 表明为哪个微服务提供回退 * 服务Id -若需要所有服务调用都支持回退-返回null 或者 * 即可 */ @Override public String getRoute() { // TODO Auto-generated method stub return "*"; } @Override public ClientHttpResponse fallbackResponse(String route, Throwable cause) { if (cause instanceof HystrixTimeoutException) { return response(HttpStatus.GATEWAY_TIMEOUT); } else { return response(HttpStatus.INTERNAL_SERVER_ERROR); } } private ClientHttpResponse response(final HttpStatus status) { return new ClientHttpResponse() { @Override public HttpStatus getStatusCode() throws IOException { //return status; return HttpStatus.BAD_REQUEST; } @Override public int getRawStatusCode() throws IOException { //return status.value(); return HttpStatus.BAD_REQUEST.value(); } @Override public String getStatusText() throws IOException { //return s