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.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.1.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Finchley.RC1</spring-cloud.version> </properties> <dependencies> <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> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>3.0.1</version> <executions> <execution> <id>copy-conf</id> <phase>package</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <encoding>UTF-8</encoding> <outputDirectory>${project.build.directory}/ext/conf</outputDirectory> <resources> <resource> <directory>ext/conf</directory> <includes> <include>logback.xml</include> </includes> <filtering>true</filtering> </resource> </resources> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.7.5.201505241946</version> <executions> <execution> <id>default-prepare-agent</id> <goals> <goal>prepare-agent</goal> </goals> </execution> <execution> <id>default-prepare-agent-integration</id> <goals> <goal>prepare-agent-integration</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <version>0.4.3</version> <configuration> <imageName>hy_uav_gateway</imageName> <dockerDirectory>src/main/docker</dockerDirectory> <resources> <resource> <targetPath>/</targetPath> <directory>${project.build.directory}</directory> <include>${project.build.finalName}.jar</include> <include>ext/conf/logback.xml</include> </resource> </resources> </configuration> </plugin> </plugins> </build> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </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網關是一個公共基礎組件,無狀態,可支持多套分布式部署。如下圖所示:

