摘自:蚂蚁课堂:http://www.mayikt.com/course/video/2414
1、微服务网关平台设计思想及作用
1、接口产生背景:在面向服务架构和微服务背景和rpc远程调用下产生,目的是为了解耦。
2、接口分类:
(1)开放接口:其他机构合作伙伴进行调用(必须在外网访问)需要通过appid+appsecret生成accesstoken进行通讯, 对接支付开发,微信开发。
目的:可以授权一些接口权限oauth2.0协议方式,第三方联合登陆。
(2)内部接口:一般只能在局域网中进行访问,经过网关进行转发请求,服务与服务调用之间关系都在同一个微服务系统中。
目的:保证安全问题。
3、接口设计考虑:接口权限(开放/内部)接口、幂等性、安全性(https)、防止篡改数据(验证签名)、使用网关拦截接口实现黑名单和白名单、接口使用http+json格式跨平台操作(http底层使用的是socket技术,转化成2进制)、考虑高并发(对接口服务实现保护 服务降级、熔断、隔离之类),最后使用统一的api管理平台api swagger
4、网关:客户端请求统一要先请求到网关服务器上,再由网关服务器进行转发到实际服务器上,类似于nginx。
作用:可以拦截客户端所有请求,对该请求进行权限控制、负载均衡、日志管理、统一异常处理、xxs、sql注入、黑名单和白名单,性能监控、日志打印、接口调用监控等。
2、网关与过滤器区别
过滤器是拦截单个tomcat服务器请求,网关是拦截整个微服务所有请求。
3、Nginx和Zuul区别
相同点:Zuul和Nginx都可以实现负载均衡、反向代理(隐藏真实ip地址),过滤请求,实现网关的效果。
不同点:
(1)Nginx采用c语言编写 , Zuul采用ava语言编写。
(2)Zuul负载均衡实现:采用ribbon+eureka实现本地负载均衡 ; Nginx负载均衡实现:采用服务器实现负载均衡 .
(3)Nginx相比zuul功能会更加强大,因为Nginx整合一些脚本语言(Nginx+lua)。
(4)Nginx适合于服务器端负载均衡 ,Zuul适合微服务中实现网关。
建议nginx + zuul实现网关,这时nginx用于实现反向代理,zuul对微服务实现网关拦截。
常用网关框架:
(1)Kong kong是基于nginx+lua进行二次开发的方案,https://konghq.com
(2)Netflix Zuul是springcloud的一个推荐组件,https://github.com/Netflix/zuul
(3)orange 是国人开发的开源程序,http://orange.sumory.com/
4、搭建SpringCloud Zuul网关平台(基于 Eureka)
1、启动Eureka注册中心服务
2、建立springcloud zuul网关平台
建立maven工程,引入依赖:
<!-- springcloud整合zuul网关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<!-- springcloud eureka-client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
配置yml文件信息
##服务端口
server.port=6089
##注册地址
eureka.client.serviceUrl.defaultZone=http://localhost:8100/eureka
##服务名称
spring.application.name=service-zuul
##定义转发服务规则
##客户端发送请求时以app-member开头,都会转发到app-member服务上去
zuul.routes.service1.path=/app-member/**
##服务别名 zuul网关默认整合ribbon,自动实现负载均衡轮训效果
zuul.routes.service1.service-id=app-member
##客户端发送请求时以app-order开头,都会转发到app-order服务上去
zuul.routes.service2.path=/app-order/**
zuul.routes.service2.service-id=app-order
##默认服务读取eureka注册服务列表,默认读取时间是间隔30秒
##开启所有断点的监控
management.endpoints.web.exposure.include=*
建立启动类,引入@EnableZuulProxy 开启网关代理
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class AppGateway {
//@EnableZuulProxy 开启网关代理
public static void main(String[] args) {
SpringApplication.run(AppGateway.class, args);
}
启动app-member服务后,通过访问zuul配置的端口和服务名称,即可访问到app-member服务而不向外暴露app-member服务的地址和端口。如:app-member服务的访问地址是:127.0.0.1:8888/app-member,通过zuul访问就是127.0.0.1:6089/app-member。
5、Zuul网关拦截参数信息
zuul网关服务中建立过滤器用于拦截请求参数,filter须继承ZuulFilter类并实现几个方法,如下:
@Component
public class TokenFilter extends ZuulFilter{
/**
* 编写过滤器拦截业务逻辑代码
*/
@Override
public Object run() throws ZuulException {
//案例:拦截所有的服务接口,判断服务接口上是否有传递usertoken参数
//获取上下文
RequestContext currentContext = RequestContext.getCurrentContext();
//获取request
HttpServletRequest request = currentContext.getRequest();
//获取token时,从请求头获取
String token = request.getParameter("userToken");
if (StringUtils.isEmpty(token)) {
//不会继续执行,不去调用服务接口,网关服务直接响应给客户端
currentContext.setSendZuulResponse(false);
currentContext.setResponseBody("usertoken is null");
currentContext.setResponseStatusCode(401);
return null;
}
//不为空的话,执行其他业务代码
return null;
}
/**
* 判断过滤器是否生效
*/
@Override
public boolean shouldFilter() {
// TODO Auto-generated method stub
return true;
}
/**
* 过滤器执行顺序,当一个请求在同一阶段的时候存在多个过滤器的时候,多个过滤器执行顺序
*/
@Override
public int filterOrder() {
// TODO Auto-generated method stub
return 0;
}
/**
* 过滤器类型pre,表示在请求之前进行执行
*/
@Override
public String filterType() {
return "pre";
}
此处是验证用户请求须传入token,请求经过网关时,如果不传入token,则会返回相对应的错误提示,传入token,才会进入正常的业务服务器执行业务。
Zuul是默认集成了ribbon并开启负载均衡,通过服务名称访问服务的时候,网关会在本地实现转发,从而实现负载均衡。
6、搭建动态Zuul网关路由转发(SpringCloud Config分布式配置中心)
(1)在Git(码云)平台建立一个yml文件,里面加入相关配置
(2)网关整合分布式配置中心,pom中添加依赖,yml添加配置:如下:
<!-- springcloud整合config-client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
<!-- 监控中心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
##服务端口
server.port=6089
##注册地址
eureka.client.serviceUrl.defaultZone=http://localhost:8100/eureka
##服务名称
spring.application.name=service-zuul
##读取版本环境(这里是开发环境或生产环境 git上的文件名称格式:服务名称-版本环境.properties)
spring.cloud.config.profile=dev
##读取分布式配置中心的服务名称
spring.cloud.config.discovery.service-id=config-server
##开启读取权限
spring.cloud.config.discovery.enabled=true
##定义转发服务规则
##开启所有断点的监控
##management.endpoints.web.exposure.include=*
(3)启动分布式配置中心,里面配置的有读取git上资源的配置,config配置中心参考: https://mp.csdn.net/postedit/103386487
(4)zuul的启动类中加入实时更新的代码:
//zuul配置能够使用config实现实时更新
@RefreshScope
@ConfigurationProperties("zuul")
public ZuulProperties zuulProperties(){
return new ZuulProperties();
}
这时候可以通过分布式配置中心从git上来读取zuul的相关配置信息。
(涉及的服务:Eureka注册中心、Config分布式配置中心、Zuul网关、服务提供者、服务消费者)