欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Zuul简介及代码示例

程序员文章站 2022-07-12 18:52:29
...
zuul它是一种怪兽,可能是因为长相太可怕了,百度居然搜不到,我们打开Spring Cloud文档

https://cloud.spring.io/spring-cloud-netflix/reference/html/#_router_and_filter_zuul

Router and Filter: Zuul

路由器和过滤器Zuul

在2微服务架构里面呢,路由是微服务架构的一部分,根路径会映射到你的WEB引用,/api/user他可能会映射到用户

微服务,这个路径会映射到你的商店微服务,Zuul是Netflix开发的,基于JVM的,路由器和服务器端的负载均衡器,我们之前

讲过客户端负载均衡机制,Ribbon,Zuul他还是服务端的负载均衡

Routing is an integral part of a microservice architecture. For example, / may be mapped to your 

web application, /api/users is mapped to the user service and /api/shop is mapped to the 

shop service. Zuul is a JVM-based router and server-side load balancer from Netflix.

认证,压力测试,动态路由,服务的迁移,减轻各个负载,静态的响应处理,还有流量的管理

Netflix uses Zuul for the following:

Authentication

Insights

Stress Testing

Canary Testing

Dynamic Routing

Service Migration

Load Shedding

Security

Static Response handling

Active/Active traffic management

Zuul的规则引擎呢,使用任意的JVM语言写的,内置可以使用JAVA和Groovy,但是理论上所有的JVM语言都可以玩,

Zuul’s rule engine lets rules and filters be written in essentially any JVM language, 

with built-in support for Java and Groovy.

这个配置项被两个配置项代替了

The configuration property zuul.max.host.connections has been replaced by two new properties, 

zuul.host.maxTotalConnections and zuul.host.maxPerRouteConnections, 

which default to 200 and 20 respectively.

隔离一个是SEMAPHORE,一个是THREAD,一个是信号,一个是线程,他在这个里面使用的信号,你也可以使用这个配置,

去把它指定成Thread

The default Hystrix isolation pattern (ExecutionIsolationStrategy) for all routes is SEMAPHORE. 

zuul.ribbonIsolationStrategy can be changed to THREAD if that isolation pattern is preferred.

http://www.github.com/netflix/hystrix

我们讲hystrix的时候有讲过他的隔离

https://github.com/netflix/hystrix/wiki

https://github.com/Netflix/Hystrix/wiki/Configuration

一个是THREAD,一个是SEMAPHORE,他说了默认的是Thread

How to Include Zuul

你要在Spring Cloud里面引入某个组建的话,你就要加上某某starter

To include Zuul in your project, use the starter with a group ID of org.springframework.cloud 

and a artifact ID of spring-cloud-starter-netflix-zuul. 

Spring Cloud创建了一个嵌入式的代理,他去简化了一种非常常见的开发,开发的方式,这种方式是什么呢,

其中UI应用程序想要去代理,一个或者是多个后端的服务的调用,他说这种特性呢,他说这种特性是比较有用的,

对于用户界面他去代理,后端的服务,对于所有后端去处理跨域,和认证的需要,CORS是Cross Orginal Resouce 

Sharing,其实就是跨域请求,可以这样理解,如果你想要使用它的话,在你的主类加上@EnableZuulProxy,本地的请求

会转发到相应的服务,按照约定,假设一个服务它的ID是users,它会用这种路径去接收请求,然后他把前缀省略掉了,

Zuul他使用的是Ribbon,通过Ribbon查询服务注册的组件,Eureka转发你要的实例,所有的请求都会在Hystrix Command

里面去执行,我们之前解析过了Hystrix Command是什么东西了,所有使用@HystrixCommand这个注解,这样所有的失败

都会在Hystrix的指标里面去显示,因为断路器都打开了,不会请求远程的服务了,相对于后端的服务Zuul

Spring Cloud has created an embedded Zuul proxy to ease the development of a common use case where 

a UI application wants to make proxy calls to one or more back end services. This feature is useful 

for a user interface to proxy to the back end services it requires, avoiding the need to manage CORS 

and authentication concerns independently for all the back ends.

To enable it, annotate a Spring Boot main class with @EnableZuulProxy. Doing so causes local calls 

to be forwarded to the appropriate service. By convention, a service with an ID of users receives 

requests from the proxy located at /users (with the prefix stripped). The proxy uses Ribbon to 

locate an instance to which to forward through discovery. All requests are executed in a hystrix 

command, so failures appear in Hystrix metrics. Once the circuit is open, the proxy does not 

try to contact the service.

Zuul其实并没有发现服务发现的客户端,他没有包含Eureka的Client,因此如果你想通过serviceId去路由的话,

你得提供依赖

microservice-gateway-zuul

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>

Zuul的依赖加好了,这个时候我们是不是还得加Eureka的依赖

the Zuul starter does not include a discovery client, so, for routes based on service IDs, 

you need to provide one of those on the classpath as well (Eureka is one choice).

@EnableZuulProxy
@SpringBootApplication
public class EurekaApplication {
  public static void main(String[] args) {
    SpringApplication.run(EurekaApplication.class, args);
  }
}

@EnableZuulProxy它是一个组合注解

@EnableCircuitBreaker
@EnableDiscoveryClient
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(ZuulProxyConfiguration.class)
public @interface EnableZuulProxy {
}

这就是为什么,我只要一个注解就可以把它注册到Eureka

localhost:7900/simple/1

localhost:8040/microservice-simple-provider-user/simple/1

所以这个就是Eureka里面的serviceId,

Mapped URL path [/microservice-simple-provider-user/**] onto handler of type 

[class org.springframework.cloud.netflix.zuul.web.ZuulController]

他其实是有一个映射的,规则也是非常简单的,比如你在eureka上有一个微服务叫abc,abc的端口

是8000,他有一个接口是/simple/1,我们使用zuul去访问的,abc是应用的名称,这就可以访问了,

但是没有完全达到我的要求,这么长一个我不喜欢,我想要改成user,我想改成这样的

localhost:8040/user/simple/1


zuul:
  routes:
    user-route:                   # 该配置方式中,user-route只是给路由一个名称,可以任意起名。
      service-id: microservice-provider-user
      path: /user/**              # service-id对应的路径
zuul.routes.user-route.service-id=microservice-simple-provider-user
zuul.routes.user-route.path=/user/** 

假设我现在有个user微服务,有个电影微服务,反向代理微服务,

默认所有注册到Eureka上的微服务

microservice-consumer-movie-ribbon-hystrix

localhost:8040/microservice-consumer-movie-ribbon-hystrix/movie/1

localhost:8010/movie/1

如果我只想代理user微服务,不想代理电影微服务,第一种办法是把所有的微服务ignore,只有你配的微服务才反向代理,

https://cloud.spring.io/spring-cloud-netflix/reference/html/#_router_and_filter_zuul

 zuul:
  ignoredServices: '*'
  routes:
    users: /myusers/**
	
第二种就是配置

zuul.ignoredServices=microservice-consumer-movie-ribbon-hystrix

多个我可以用逗号

/**
 * Set of service names not to consider for proxying automatically. By default all
 * services in the discovery client will be proxied.
 */
private Set<String> ignoredServices = new LinkedHashSet<>();

他是一个Set,我们可以用逗号分隔开
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.learn.cloud</groupId>
	<artifactId>microservice-gateway-zuul</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	 <parent>
	   <groupId>cn.learn</groupId>
	   <artifactId>microcloud02</artifactId>
	   <version>0.0.1</version>
	 </parent>
	
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>	
	
	<dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
            <version>1.4.2.RELEASE</version>
        </dependency>
		<dependency>
		    <groupId>org.springframework.cloud</groupId>
		    <artifactId>spring-cloud-starter-zuul</artifactId>
		</dependency>
	</dependencies>
	
	<!-- 这个插件,可以将应用打包成一个可执行的jar包 -->
	<build>
	    <plugins>
	        <plugin>
	            <groupId>org.springframework.boot</groupId>
	            <artifactId>spring-boot-maven-plugin</artifactId>
	        </plugin>
	    </plugins>
	</build>

  
</project>
server.port=8040
spring.application.name=microservice-gateway-zuul
eureka.instance.prefer-ip-address=true
eureka.instance.instance-id=${spring.application.name}:${spring.cloud.client.ipAddress}:${spring.application.instance_id:${server.port}}
eureka.client.serviceUrl.defaultZone=http://admin:[email protected]:8761/eureka
eureka.instance.appname=microservice-gateway-zuul
zuul.routes.user-route.service-id=microservice-simple-provider-user
#zuul.ignoredServices=microservice-consumer-movie-ribbon-hystrix
zuul.routes.user-route.path=/user/**
package com.learn.cloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@EnableZuulProxy
@SpringBootApplication
public class GateWayZuulApplication {
  public static void main(String[] args) {
    SpringApplication.run(GateWayZuulApplication.class, args);
  }
}