Spring Zuul API网关
1.网关
1.1 网关相关概念
与过滤器、拦截器等技术点相似,为什么有网关的存在?
负载均衡是Ribbon实现的,Ribbon是本地的客户端负载均衡。Nginx是软负载。
网关核心的应用场景:路由地址、反向代理、黑名单与白名单、授权安全
1.1.1域名解析
域名解析:将域名转换为ip地址。
步骤:1.浏览器先查找缓存;
2.没有缓存则从hosts文件查找ip与域名映射,将域名转换为ip;
3.hosts中没有查到对应的ip,则直接连接外网宽带运营商获取对应的ip;
1.1.2 企业网关是如何架构的
域名->解析得到ip->Ivs+Keeplived(虚拟的VIP)->轮询到主Nginx和备Nginx->网关
lvs 负载均衡是四层负载均衡 基于Ip地址+端口,可以管理Nginx集群。
外网如何部署lvs.
Nginx基本要求:一主一备。
网关集群 集群目的是高可用。
Zuul使用Java写的,Nginx使用C写的。Nginx功能比Zuul功能强大,Nginx实现反向代理功能性能比Zuul要好。但是Nginx是针对服务器的,Zuul是微服务专用的,编写一些拦截、日志、权限、限流等业务要方便得多。各自有应用场景,不能相互替代。
1.1.3 如何搭建网关
1.Nginx如何搭建网关
通过反向代理搭建网关,有一个重要的应用场景是解决跨域问题
2.设计RPC框架的思路
远程调用框架,核心在服务治理,最核心在注册中心。
可选的注册中心: Eureka ,Consul,Zookeeper
SOA 把共同的业务逻辑抽取出来,已接口形式发布,服务化。
注册中心关键:记录服务名与IP端口的映射,消费者工程通过注册中心获取到指定服务名对应的Ip和端口,进行调用。
1.2 Spring Cloud Zuul
基于Eureka环境下,已有两个服务service_a和service_b,创建工程zuulgateway项目。
1.2.1 配置pom.xml
创建工程,配置pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
1.2.2 配置application.yml
###注册 中心
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8100/eureka/
server:
port: 80
###网关名称
spring:
application:
name: service-zuul
### 配置网关反向代理
zuul:
routes:
api-a:
path: /api-a/**
serviceId: service_a
api-b:
path: /api-b/**
serviceId: service_b
1.2.3 主启动类
@EnableZuulProxy // @EnableZuulProxy 开启Zuul网关代理
@EnableEurekaClient // @EnableEurekaClient 注册到Eureka
@SpringBootApplication
public class AppZuul {
public static void main(String[] args) {
SpringApplication.run(AppZuul.class, args);
}
// 注册到SpringBoot 容器
@Bean
public TokenFilter accessFilter() {
return new TokenFilter();
}
}
1.2.4 使用网关判断权限
// 验证Tomcat 参数
public class TokenFilter extends ZuulFilter {
/*
* (non-Javadoc)
*
* @see com.netflix.zuul.IZuulFilter#run()
*/
public Object run() throws ZuulException {
// 拦截参数执行业务逻辑
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
String token = request.getParameter("token");
if (StringUtils.isEmpty(token)) {
// 直接不能够继续执行下面业务逻辑
ctx.setSendZuulResponse(false); // 不继续执行下面业务逻辑
ctx.setResponseStatusCode(500);// 不继续执行下面业务逻辑
ctx.setResponseBody("token is null");
return null;
}
// 继续正常执行业务逻辑
return null;
}
/*
* (non-Javadoc)
*
* @see com.netflix.zuul.IZuulFilter#shouldFilter()
*/
public boolean shouldFilter() {
return true; // 是否开启当前ilter(
}
/*
* (non-Javadoc)
*
* @see com.netflix.zuul.ZuulFilter#filterOrder()
*/
@Override
public int filterOrder() {
return 0; // 过滤器优先级 数字越大 越优先执行大
}
@Override
public String filterType() {
return "pre";// 前置执行
}
}