APIGateway网关安全设计
Spring Cloud里面有个组件 Zuul网关
网关和 过滤器 拦截器很相似
网关可以实现过滤器 拦截器的功能 而且可以实现Nginx的基本功能 反向代理 负载均衡ribbon
Nginx是软负载 ribbon本底客户端负载均衡
网关的核心基本作用: 路由地址 反向代理 黑名单与白名单系统(HTTP请求头的来源字段) 授权安全
DNS过程:先浏览器缓存 然后本底host文件 最后外网DNS解析 最终获取IP地址
访问虚拟的VIP
lvs是四层负载均衡 基于IP+端口号 可以管理Nginx集群
外网部署LVS (阿里云有负载均衡器可以买)
Nginx基本要求: 一主一备
Nginx走完再走网关
网关可以拦截所有服务请求: 日志管理 权限控制 限流 安全控制
既然Nginx可以实现网关,为什么需要Zuul。
Zuul使用Java开发的 。Nginx是C开发的。Nginx功能比Zuul更强大。Zuul针对微服务的,Nginx针对服务器的。
Zuul框架是微服务里面的一个组件,网关。
注意: LVS管理Nginx
搭建网关:
1、Nginx也可以实现网关。
a. 基于域名区分
b.基于项目名称
拦击域名进行跳转:
访问:
2、基于SpringCloud Zuul搭建网关
Eureka
服务A
服务B
网关的核心配置:
### 配置网关反向代理
zuul:
routes:
api-a:
path: /api-a/**
serviceId: toov5_a ##服务名称
api-b:
path: /api-b/**
serviceId: toov5_b ##服务名称
所以:
###注册 中心
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8100/eureka/
server:
port: 80
###网关名称
spring:
application:
name: service-zuul
### 配置网关反向代理
zuul:
routes:
api-a:
path: /api-a/**
serviceId: toov5_a
api-b:
path: /api-b/**
serviceId: toov5_b
pom:
<parent> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-parentartifactId> <version>2.0.1.RELEASEversion> <relativePath /> parent> <properties> <project.build.sourceEncoding>UTF-8project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding> <java.version>1.8java.version> <spring-cloud.version>Finchley.RC1spring-cloud.version> properties> <dependencies> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starterartifactId> dependency> <dependency> <groupId>org.springframework.cloudgroupId> <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId> dependency> <dependency> <groupId>org.springframework.cloudgroupId> <artifactId>spring-cloud-starter-netflix-ribbonartifactId> dependency> <dependency> <groupId>org.springframework.cloudgroupId> <artifactId>spring-cloud-starter-netflix-zuulartifactId> dependency> <dependency> <groupId>org.projectlombokgroupId> <artifactId>lombokartifactId> <optional>trueoptional> dependency> <dependency> <groupId>com.alibabagroupId> <artifactId>fastjsonartifactId> <version>1.2.3version> dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-testartifactId> <scope>testscope> dependency> dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloudgroupId> <artifactId>spring-cloud-dependenciesartifactId> <version>${spring-cloud.version}version> <type>pomtype> <scope>importscope> dependency> dependencies> dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-maven-pluginartifactId> plugin> <plugin> <groupId>org.apache.maven.pluginsgroupId> <artifactId>maven-compiler-pluginartifactId> <configuration> <source>1.8source> <target>1.8target> configuration> plugin> <plugin> <groupId>org.apache.maven.pluginsgroupId> <artifactId>maven-resources-pluginartifactId> <version>3.0.1version> <executions> <execution> <id>copy-confid> <phase>packagephase> <goals> <goal>copy-resourcesgoal> goals> <configuration> <encoding>UTF-8encoding> <outputDirectory>${project.build.directory}/ext/confoutputDirectory> <resources> <resource> <directory>ext/confdirectory> <includes> <include>logback.xmlinclude> includes> <filtering>truefiltering> resource> resources> configuration> execution> executions> plugin> <plugin> <groupId>org.jacocogroupId> <artifactId>jacoco-maven-pluginartifactId> <version>0.7.5.201505241946version> <executions> <execution> <id>default-prepare-agentid> <goals> <goal>prepare-agentgoal> goals> execution> <execution> <id>default-prepare-agent-integrationid> <goals> <goal>prepare-agent-integrationgoal> goals> execution> executions> plugin> <plugin> <groupId>com.spotifygroupId> <artifactId>docker-maven-pluginartifactId> <version>0.4.3version> <configuration> <imageName>hy_uav_gatewayimageName> <dockerDirectory>src/main/dockerdockerDirectory> <resources> <resource> <targetPath>/targetPath> <directory>${project.build.directory}directory> <include>${project.build.finalName}.jarinclude> <include>ext/conf/logback.xmlinclude> resource> resources> configuration> plugin> plugins> build> <repositories> <repository> <id>spring-milestonesid> <name>Spring Milestonesname> <url>https://repo.spring.io/milestoneurl> <snapshots> <enabled>falseenabled> snapshots> repository> repositories>
Filter:
import javax.servlet.http.HttpServletRequest; import org.springframework.util.StringUtils; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; // 验证Tomcat 参数 public class TokenFilter extends ZuulFilter { 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; } public boolean shouldFilter() { return true; // 是否开启当前ilter( } @Override public int filterOrder() { return 0; // 过滤器优先级 数字越大 越优先执行大 } @Override public String filterType() { return "pre";// 前置执行 } }
启动类:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; import org.springframework.context.annotation.Bean; import com.itmayiedu.filter.TokenFilter; @EnableZuulProxy @EnableEurekaClient @SpringBootApplication public class AppZuul { // @EnableZuulProxy 开启Zuul网关代理 // @EnableEurekaClient 注册到EurekaC public static void main(String[] args) { SpringApplication.run(AppZuul.class, args); } // 注册到SpringBoot 容器 @Bean public TokenFilter accessFilter() { return new TokenFilter(); } }
补充:
自己实现一套RPC远程调用框架。如何设计?
核心在服务治理。
传统服务与服务之间通讯URL地址管理 包括实现负载均衡 熔断机制 服务降级
服务和服务之间的依赖关系 (注册中心)
API网关是一个公共基础组件,无状态,可支持多套分布式部署。如下图所示: