源无极

导航

 

 

1、微服务网关介绍和使用场景
简介:讲解网关的作用和使用场景 (画图)

 


1)什么是网关
API Gateway,是系统的唯一对外的入口,介于客户端和服务器端之间的中间层,处理非业务功能 提供路由请求、鉴权、监控、缓存、限流等功能

统一接入
智能路由
AB测试、灰度测试
负载均衡、容灾处理
日志埋点(类似Nignx日志)

流量监控
限流处理
服务降级

安全防护
鉴权处理
监控
机器网络隔离


2)主流的网关
zuul:是Netflix开源的微服务网关,和Eureka,Ribbon,Hystrix等组件配合使用,Zuul 2.0比1.0的性能提高很多

kong: 由Mashape公司开源的,基于Nginx的API gateway

nginx+lua:是一个高性能的HTTP和反向代理服务器,lua是脚本语言,让Nginx执行Lua脚本,并且高并发、非阻塞的处理各种请求

 

2、SpringCloud的网关组件zuul基本使用
简介:讲解zuul网关基本使用

创建工程

1)在任意工程下,File  >>  NEW project

2)

3)

 

1、加入依赖

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 4     <modelVersion>4.0.0</modelVersion>
 5     <parent>
 6         <groupId>org.springframework.boot</groupId>
 7         <artifactId>spring-boot-starter-parent</artifactId>
 8         <version>2.0.4.RELEASE</version>
 9         <relativePath/> <!-- lookup parent from repository -->
10     </parent>
11     <groupId>com.po</groupId>
12     <artifactId>api-gateway</artifactId>
13     <version>0.0.1-SNAPSHOT</version>
14     <name>api-gateway</name>
15     <description>Demo project for Spring Boot</description>
16 
17     <properties>
18         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
19         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
20         <java.version>1.8</java.version>
21         <spring-cloud.version>Finchley.SR1</spring-cloud.version>
22     </properties>
23 
24     <dependencies>
25         <dependency>
26             <groupId>org.springframework.cloud</groupId>
27             <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
28         </dependency>
29         <dependency>
30             <groupId>org.springframework.cloud</groupId>
31             <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
32         </dependency>
33 
34         <dependency>
35             <groupId>org.springframework.boot</groupId>
36             <artifactId>spring-boot-starter-test</artifactId>
37             <scope>test</scope>
38         </dependency>
39     </dependencies>
40 
41     <dependencyManagement>
42         <dependencies>
43             <dependency>
44                 <groupId>org.springframework.cloud</groupId>
45                 <artifactId>spring-cloud-dependencies</artifactId>
46                 <version>${spring-cloud.version}</version>
47                 <type>pom</type>
48                 <scope>import</scope>
49             </dependency>
50         </dependencies>
51     </dependencyManagement>
52 
53     <build>
54         <plugins>
55             <plugin>
56                 <groupId>org.springframework.boot</groupId>
57                 <artifactId>spring-boot-maven-plugin</artifactId>
58             </plugin>
59         </plugins>
60     </build>
61 
62     
63 
64 </project>

 

 

yml

server:
  port: 9000
#服务名称

spring:
  application:
    name: api-gateway

#指定注册中心地址
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

 


2、启动类加入注解 @EnableZuulProxy
默认集成断路器 @EnableCircuitBreaker

 1 //
 2 // Source code recreated from a .class file by IntelliJ IDEA
 3 // (powered by Fernflower decompiler)
 4 //
 5 
 6 package org.springframework.cloud.netflix.zuul;
 7 
 8 import java.lang.annotation.ElementType;
 9 import java.lang.annotation.Retention;
10 import java.lang.annotation.RetentionPolicy;
11 import java.lang.annotation.Target;
12 import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
13 import org.springframework.context.annotation.Import;
14 
15 @EnableCircuitBreaker
16 @Target({ElementType.TYPE})
17 @Retention(RetentionPolicy.RUNTIME)
18 @Import({ZuulProxyMarkerConfiguration.class})
19 public @interface EnableZuulProxy {
20 }

 

默认访问规则
http://gateway:port/service-id/**

例子:默认 /order-service/api/v1/order/save?user_id=2&product_id=1
自定义 /xdclass_order/api/v1/order/save?user_id=2&product_id=1

比如:

http://localhost:8781/api/vi/order/save?product_id=2&user_id=5

数据如下:

{"code":0,"data":{"id":0,"productName":"\"iPhone7data from port = 8771\"","tradeNo":"2ca0043f-b105-4707-9aa5-8f4727a1abf5","price":7999,"createTime":"2019-01-06T09:37:50.100+0000","userId":5,"userName":null}}

 

现在通过网关访问

http://localhost:9000/order-service/api/vi/order/save?product_id=2&user_id=5

数据如下:

{"code":0,"data":{"id":0,"productName":"\"iPhone7data from port = 8771\"","tradeNo":"a43c4dd2-f978-4612-97aa-abb2fb735dba","price":7999,"createTime":"2019-01-06T09:39:50.436+0000","userId":5,"userName":null}}

 

同理其他访问

http://localhost:9000/product-service/api/vi/product/findById?id=2

{"id":2,"name":"iPhone7data from port = 8771","price":7999,"store":20}

自定义路由转发:

1 zuul:
2   routes:
3     order-service: /apigateway/**

http://localhost:9000/apigateway/api/vi/order/save?product_id=2&user_id=5

{"code":0,"data":{"id":0,"productName":"\"iPhone7data from port = 8771\"","tradeNo":"30bae8a6-ccef-49a0-b9fd-06f3afaceb28","price":7999,"createTime":"2019-01-06T09:53:54.154+0000","userId":5,"userName":null}}

 


环境隔离配置:
需求 :不想让默认的服务对外暴露接口
/order-service/api/v1/order/save

配置:

1 #自定义路由映射
2 zuul:
3   routes:
4     order-service: /apigateway/**
5     product-service: /apigateway/**
6   #统一入口为上面的配置,其他入口忽略
7   ignored-patterns: /*-service/**
8   #忽略整个服务,对外提供接口
9   #ignored-services: product-service

 

 

分析:

    这样配置之后,访问路径含有service都不行了,必须是apigateway前缀

/**是任意内容的:均可以访问

经测试将第二个会覆盖第一个,

也就是http://localhost:9000/apigateway/api/vi/order/save?product_id=2&user_id=5访问失败

http://localhost:9000/apigateway/api/vi/product/list可以访问

所有配置修改:

 

1 #自定义路由映射
2 zuul:
3   routes:
4     order-service: /apigateway/order/**
5     product-service: /apigateway/product/**   #统一入口为上面的配置,其他入口忽略
7   ignored-patterns: /*-service/**
8   #忽略整个服务,对外提供接口
9   #ignored-services: product-service

 

 

 

http://localhost:9000/apigateway/order/api/vi/order/save?product_id=2&user_id=5
http://localhost:9000/apigateway/product/api/vi/product/list

注意:如果知道ip也是可以访问的

http://localhost:8771/api/vi/product/findById?id=2

 补充:服务之间的调用都是通过内网访问

 

 

 

3、高级篇幅之Zuul常用问题分析和网关过滤器原理分析

简介:讲解Zuul网关原理和过滤器生命周期,

1、路由名称定义问题
路由映射重复覆盖问题

1 #自定义路由映射
2 zuul:
3   routes:
4     order-service: /apigateway/order/**
5     product-service: /apigateway/product/**   #统一入口为上面的配置,其他入口忽略
7   ignored-patterns: /*-service/**
8   #忽略整个服务,对外提供接口
9   #ignored-services: product-service

 


2、Http请求头过滤问题

1)对order-service服务的save方法进行修改

 1 @RequestMapping("save")
 2     @HystrixCommand(fallbackMethod = "saveOrderFail")//调用save方法失败则执行saveOrderFail的方法
 3     public  Object save(@RequestParam("user_id")int userId, @RequestParam("product_id")int productId, HttpServletRequest request){
 4         String token = request.getHeader("token");
 5         String cookie = request.getHeader("cookie");
 6         System.out.println("token= "+token);
 7         System.out.println("cookie= "+cookie);
 8         Map<String, Object> data = new HashMap<>();
 9         data.put("code",0);
10         data.put("data",productOrderService.save(userId,productId));
11         return data;
12     }

 

 

通过Postman访问,在Headers添加token,cookie

控制台

1 token= sdasdsadasd
2 cookie= null

 

 cookie没有值?

 为什么呢?

routes源码下
ZuulProperties类
1 private Set<String> sensitiveHeaders = new LinkedHashSet<>(
2             Arrays.asList("Cookie", "Set-Cookie", "Authorization"));

 

已经过滤掉cookie,set-cookie,Authorization这三个参数

 

1 #自定义路由映射
2 zuul:
3   routes:
4     order-service: /apigateway/order/**
5     product-service: /apigateway/product/**
6   #统一入口为上面的配置,其他入口忽略
7   ignored-patterns: /*-service/**
8   #处理http请求头为空的问题
9   sensitive-headers:

 注意:其实zuul就是filter结集合

 

 

4、自定义Zuul过滤器实现登录鉴权实战
简介:自定义Zuul过滤器实现登录鉴权实战

 在api-gateway服务下

1、新建一个filter包

2、新建一个类,实现ZuulFilter,重写里面的方法


 ACL访问控制列表,将路径(/apigateway/order/api/vi/order/save)存放到redis里面

3、在类顶部加注解,@Component,让Spring扫描

 

 1 package com.po.apigateway.filter;
 2 
 3 import com.netflix.zuul.ZuulFilter;
 4 import com.netflix.zuul.context.RequestContext;
 5 import com.netflix.zuul.exception.ZuulException;
 6 import org.apache.commons.lang.StringUtils;
 7 import org.springframework.http.HttpStatus;
 8 import org.springframework.stereotype.Component;
 9 import javax.servlet.http.HttpServletRequest;
10 
11 import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
12 /*
13 登入过滤器
14  */
15 @Component
16 public class LoginFilter extends ZuulFilter {
17 
18     /*
19     前置过滤器
20      */
21     @Override
22     public String filterType() {
23         return PRE_TYPE;
24     }
25     /**
26      * 过滤器顺序,越小越先执行
27      * @return
28      */
29     @Override
30     public int filterOrder() {
31         return 4;
32     }
33     /**
34      * 过滤器是否生效
35      * @return
36      */
37     @Override
38     public boolean shouldFilter() {
39         RequestContext currentContext = RequestContext.getCurrentContext();
40         HttpServletRequest request = currentContext.getRequest();
41         //System.out.println("路径1: "+request.getRequestURL());//http://localhost:9000/apigateway/product/api/vi/product/list
42        // System.out.println("路径2: "+request.getRequestURI());// /apigateway/product/api/vi/product/list
43         if("/apigateway/order/api/vi/order/save".equalsIgnoreCase(request.getRequestURI())){
44             return true;//拦截
45         }else if("/apigateway/product/api/vi/product/list".equalsIgnoreCase(request.getRequestURI())){
46             return true;
47         }else if("/apigateway/product/api/vi/product/findById".equalsIgnoreCase(request.getRequestURI())){
48             return true;
49         }
50         return false;
51     }
52     /**
53      * 业务逻辑
54      * @return
55      */
56     @Override
57     public Object run() throws ZuulException {
58 
59         System.out.println("拦截了 ");
60         RequestContext requestContext = RequestContext.getCurrentContext();
61         HttpServletRequest request = requestContext.getRequest();
62         String token = request.getHeader("token");
63         if(StringUtils.isBlank(token)){//post请求的话
64              token = request.getParameter("token");
65         }
66         if(StringUtils.isBlank(token)){ //登录校验逻辑  根据公司情况自定义 JWT技术
67             requestContext.setSendZuulResponse(false);//不往下走
68             //响应回去状态码 实际开发中对客户访问会带加密过的token过来,解密再判断是否为null,查数据库太慢了
69             requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
70         }
71         return null;
72     }
73 }

 

流程: shouldFilter方法中返回true,才会执行ZuulException 方法。

 

 

5、高级篇幅之高并发情况下接口限流特技
简介:谷歌guava框架介绍,网关限流使用

1、nginx层限流

2、网关层限流

 在filter包下

 1 package com.po.apigateway.filter;
 2 
 3 import com.google.common.util.concurrent.RateLimiter;
 4 import com.netflix.zuul.ZuulFilter;
 5 import com.netflix.zuul.context.RequestContext;
 6 import com.netflix.zuul.exception.ZuulException;
 7 import org.springframework.http.HttpStatus;
 8 import org.springframework.stereotype.Component;
 9 
10 import javax.servlet.http.HttpServletRequest;
11 
12 import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
13 /*
14 订单限流
15  */
16 @Component
17 public class OrderRateLimiter extends ZuulFilter {
18     //每秒产生1000个令牌
19  private  static  final RateLimiter RATE_LIMITER=RateLimiter.create(1000);
20 
21     @Override
22     public String filterType() {
23         return PRE_TYPE;
24     }
25 
26     @Override
27     public int filterOrder() {
28         return -4;
29     }
30 
31     @Override
32     public boolean shouldFilter() {
33         RequestContext currentContext = RequestContext.getCurrentContext();
34         HttpServletRequest request = currentContext.getRequest();
35         if("/apigateway/order/api/vi/order/save".equalsIgnoreCase(request.getRequestURI())){
36             return true;//拦截
37         }
38         return false;
39     }
40 
41     @Override
42     public Object run() throws ZuulException {
43         RequestContext requestContext = RequestContext.getCurrentContext();
44         if(!RATE_LIMITER.tryAcquire()){//太多请求
45             requestContext.setSendZuulResponse(false);
46             requestContext.setResponseStatusCode(HttpStatus.TOO_MANY_REQUESTS.value());
47         }
48         return null;
49     }
50 }

 

 

6、Zuul微服务网关集群搭建
简介:微服务网关Zull集群搭建

 

 

1、nginx+lvs+keepalive
https://www.cnblogs.com/liuyisai/p/5990645.html

 

posted on 2019-01-10 22:07  源无极  阅读(155)  评论(0编辑  收藏  举报