SpringCloud(六)学习笔记之Zuul
Zuul 在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架。Zuul 相当于是设备和 Netflix 流应用的 Web 网站后端所有请求的前门
Hystrix+Ribbon(不使用Feign)
一、构建Eureka Server
【基于第二章节创建的Eureka Server】
二、构建Eureka Client提供者
mhb-cloud-zuul-producer【端口:1002】
普通的Eureka Client项目 配置略......
com\applesnt\controller\ProducerController.java
package com.applesnt.controller;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/producer")
public class ProducerController {
@GetMapping("/get/web")
public String getId(){
return "返回值为:producer";
}
}
三、构建Eureka Client消费者集群
mhb-cloud-zuul-consumer 【端口:1000】
mhb-cloud-zuul-consumer2 【端口:1001】
1:pom文件
<!--eureka客户端环境支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2:application.yml
mhb-cloud-zuul-consumer和mhb-cloud-zuul-consumer2只有端口不一样
debug: false
spring:
application:
name: mhb-cloud-zuul-consumer #每一个微服务必须有这个应用名称
server:
port: 1000 #端口
eureka:
instance:
appname: zuul-consumer #eureka application的名称
prefer-ip-address: true #开启ip显示eureka的主机服务
#eureka仪表盘的Instances格式
instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
client:
service-url:
defaultZone: http://admin:123456@eureka1.com:8761/eureka/,http://admin:123456@eureka2.com:8762/eureka/,http://admin:123456@eureka3.com:8763/eureka/
#从eureka服务器注册表中获取注册表信息的时间间隔,默认30s
registry-fetch-interval-seconds: 30
#客户端发送变化同步到eureka服务器的时间间隔 默认30s
instance-info-replication-interval-seconds: 30
#询问eureka服务url信息的变化的间隔时间 默认300s
eureka-service-url-poll-interval-seconds: 300
#最初同步到eureka服务器的时间 默认40s
initial-instance-info-replication-interval-seconds: 40
#注册表是否压缩
g-zip-content: true
#eureka等待超时时间 默认是5s
eureka-server-connect-timeout-seconds: 5
#eureka等待读取时间 默认是8s
eureka-server-read-timeout-seconds: 8
3:启动类
package com.applesnt;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableEurekaClient
public class MhbCloudZuulConsumer2Application {
public static void main(String[] args) {
SpringApplication.run(MhbCloudZuulConsumer2Application.class, args);
}
@Bean
@LoadBalanced/* 负载均衡 */
public RestTemplate balanceRestTemplate(){
return new RestTemplate();
}
}
4:消费者controller
两个消费者controller 只有打印信息不同,为了看到集群效果
com\applesnt\controller\ConsumerController.java
package com.applesnt.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class ConsumerController {
@Autowired
private RestTemplate balanceRestTemplate;
@GetMapping("/get/web")
public String getId(){
System.out.println("进入comsumer01");
//eureka方式 需要在启动类的RestTemplate加上@LoadBalanced负载均衡的注解
String returnId = balanceRestTemplate.getForObject("http://mhb-cloud-zuul-producer/producer/get/web",String.class);
System.out.println("returnId = "+returnId);
return returnId;
}
}
四、构建Zuul网关项目
mhb-cloud-zuul 【提供者 端口:8080】
1:pom文件
<!--eureka客户端环境支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--zuul环境支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
2:启动类开启Zuul支持
@@EnableEurekaClient
@EnableZuulProxy
package com.applesnt;
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;
@SpringBootApplication
@EnableEurekaClient/*eureka支持*/
@EnableZuulProxy/*Zuul注解*/
public class MhbCloudZuulApplication {
public static void main(String[] args) {
SpringApplication.run(MhbCloudZuulApplication.class, args);
}
}
3:application.yml文件
debug: false
spring:
application:
name: mhb-cloud-zuul #每一个微服务必须有这个应用名称
server:
port: 8080 #端口
eureka:
instance:
appname: zuul #eureka application的名称
prefer-ip-address: true #开启ip显示eureka的主机服务
#eureka仪表盘的Instances格式
instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
client:
service-url:
defaultZone: http://admin:123456@eureka1.com:8761/eureka/,http://admin:123456@eureka2.com:8762/eureka/,http://admin:123456@eureka3.com:8763/eureka/
#zuul自定义写法
zuul:
routes:
zuul-consumer: #自定义名称 必须要写path和serviceId
path: /web/** #只要路径上有web 就会自动定位到mhb-cloud-zuul-consumer服务器上
serviceId: mhb-cloud-zuul-consumer #服务名称 默认就支持负载均衡
4:zuul测试访问
http://127.0.0.1:8080/web/get/web
请求从zuul网关服务器上转发到消费者服务器上,在远程调用提供者的controller

日志信息:负载均衡


5:zuul路由规则
1》精简写法:http://127.0.0.1:8080/web/get/web
#精简写法:
zuul:
routes:
mhb-cloud-zuul-consumer: /web/** #路由名称如果是服务器名 就可以不用写path和serviceId
2》静态路由:http://127.0.0.1:8080/web/get/web
#静态url
zuul:
routes:
my-routes: #名称自定义
path: /web/**
url: http://127.0.0.1:1000
3》静态路由负载均衡:http://127.0.0.1:8080/web/get/web
zuul:
routes:
my-routes: #名称自定义
path: /web/**
serviceId: myurl
ribbon:
eureka:
enabled: false
myurl:
ribbon:
listOfServers: http://127.0.0.1:1000,http://127.0.0.1:1001
4》忽略服务
zuul:
ignored-services: '*' #忽略所有默认的隐射机制 只路由指定的服务
ignored-services: mhb-cloud-zuul-producer #忽略指定的服务
5》忽略请求:http://127.0.0.1:8080/web/get/web (无法访问)
zuul:
ignoredPatterns: /**/get/** #过滤路径中有get请求的
routes:
zuul-consumer: #自定义名称 必须要写path和serviceId
path: /web/** #只要路径上有web 就会自动定位到mhb-cloud-zuul-consumer服务器上
serviceId: mhb-cloud-zuul-consumer
6》请求前缀
访问zuul网关:http://127.0.0.1:8080/api/web/get/web?token=123
转发后请求地址:http://mhb-cloud-zuul-consumer/web/get/web?token=123
strip-prefix: true 转发后会把前缀去掉
zuul:
routes:
zuul-consumer: #自定义名称 必须要写path和serviceId
path: /web/** #只要路径上有web 就会自动定位到mhb-cloud-zuul-consumer服务器上
serviceId: mhb-cloud-zuul-consumer
prefix: /api
strip-prefix: true
访问zuul网关:http://127.0.0.1:8080/api/web/get/web?token=123
转发后请求地址:http://mhb-cloud-zuul-consumer/api/web/get/web?token=123
strip-prefix: false 转发后会把前缀也一并带上
zuul:
routes:
zuul-consumer: #自定义名称 必须要写path和serviceId
path: /web/** #只要路径上有web 就会自动定位到mhb-cloud-zuul-consumer服务器上
serviceId: mhb-cloud-zuul-consumer
prefix: /api
strip-prefix: false
四:Zuul过滤器
mhb-cloud-zuul项目中构建AccessFilter 并继承 ZuulFilter
com\applesnt\filter\AccessFilter.java
示例:
访问网关请求的时候必须传递一个token,否则就返回拦截信息
package com.applesnt.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
@Component /*不要忘记此注解*/
@Slf4j
public class AccessFilter extends ZuulFilter{
/**
* 过滤器类型选择:
* pre 为路由前
* route 为路由过程中
* post 为路由过程后
* error 为出现错误的时候
*/
@Override
public String filterType() {
return "pre";
}
/**
* 用来过滤器排序执行的
* @return 排序的序号
*/
@Override
public int filterOrder() {
return 0;
}
/**
* 返回true表示执行这个过滤器
*/
@Override
public boolean shouldFilter() {
return true;
}
/**
* 过滤器的逻辑
*/
@Override
public Object run() {
//获取当前请求上下文
RequestContext ctx = RequestContext.getCurrentContext();
//取出当前请求
HttpServletRequest request = ctx.getRequest();
String token = request.getParameter("token");
if(StringUtils.isEmpty(token)){
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
ctx.getResponse().setContentType("text/html;charset=UTF-8");
ctx.setResponseBody("请求异常 token为空");
}
log.info("进入访问过滤器,访问的url:{},访问的方法:{}",request.getRequestURL(),request.getMethod());
return null;
}
}
测试访问:
http://127.0.0.1:8080/web/get/web (不带token参数)



浙公网安备 33010602011771号