版权声明:Copyright ©2018-2019 凉白开不加冰 版权所有 https://blog.csdn.net/qq_21082615/article/details/91371252
介绍: zuul的主要功能是路由和过滤器。
第一步:pom加入依赖包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.marcosbarbero.cloud</groupId>
<artifactId>spring-cloud-zuul-ratelimit</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
<version>1.4.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
第二步:zuul初始配置类
import com.example.route.ZuulRouteLocator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Author: 凉白开不加冰
* @Version: 0.0.1V
* @Date: 2018/7/23
* @Description: 路由初始化
**/
@Configuration
public class ZuulConfig {
@Autowired
private ZuulProperties zuulProperties;
@Autowired
private ServerProperties server;
@Bean
public ZuulRouteLocator routeLocator() {
ZuulRouteLocator routeLocator = new ZuulRouteLocator(server.getServlet().getServletPrefix(), this.zuulProperties);
return routeLocator;
}
}
第三步:动态路由类
import com.example.constant.ZuulRouteEnum;
import com.example.pojo.vo.ZuulRouteVO;
import com.example.tools.RedisTools;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.RefreshableRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.SimpleRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* @Author: 凉白开不加冰
* @Version: 0.0.1V
* @Date: 2018/7/23
* @Description: 动态路由
**/
@Slf4j
public class ZuulRouteLocator extends SimpleRouteLocator implements RefreshableRouteLocator {
@Autowired
private StringRedisTemplate stringRedisTemplate;
private ZuulProperties properties;
public ZuulRouteLocator(String servletPath, ZuulProperties properties) {
super(servletPath, properties);
this.properties = properties;
log.info("servletPath:{}", servletPath);
}
@Override
public void refresh() {
doRefresh();
}
@Override
protected Map<String, ZuulProperties.ZuulRoute> locateRoutes() {
LinkedHashMap<String, ZuulProperties.ZuulRoute> routesMap = new LinkedHashMap<>();
//从application.properties中加载路由信息
routesMap.putAll(super.locateRoutes());
//从redis中加载路由信息
routesMap.putAll(locateRoutesFromRedis());
log.info("网关路由配置 --> {}", routesMap);
//优化一下配置
LinkedHashMap<String, ZuulProperties.ZuulRoute> values = new LinkedHashMap<>();
for (Map.Entry<String, ZuulProperties.ZuulRoute> entry : routesMap.entrySet()) {
String path = entry.getKey();
if (!path.startsWith("/")) {
path = "/" + path;
}
if (StringUtils.hasText(this.properties.getPrefix())) {
path = this.properties.getPrefix() + path;
if (!path.startsWith("/")) {
path = "/" + path;
}
}
values.put(path, entry.getValue());
}
return values;
}
/**
* @Author: 凉白开不加冰
* @Date: 2018/7/23 18:14
* @Description: 从redis获取路由信息
**/
private Map<String, ZuulProperties.ZuulRoute> locateRoutesFromRedis() {
Map<String, ZuulProperties.ZuulRoute> routes = new LinkedHashMap<>();
List<ZuulRouteVO> results = RedisTools.hget(stringRedisTemplate,ZuulRouteEnum.ZUUL_ROUTE_LIST.getKey(), ZuulRouteVO.class);
if(results==null){
return routes;
}
for (ZuulRouteVO result : results) {
if (StringUtils.isEmpty(result.getPath())) {
continue;
}
if (!result.getEnabled()) {
continue;
}
ZuulProperties.ZuulRoute zuulRoute = new ZuulProperties.ZuulRoute();
try {
BeanUtils.copyProperties(result, zuulRoute);
} catch (Exception e) {
log.error("=============加载网关路由失败==============", e);
}
routes.put(zuulRoute.getPath(), zuulRoute);
}
return routes;
}
}
路由限流枚举
import lombok.Getter;
import lombok.Setter;
/**
* @Author: 凉白开不加冰
* @Version: 0.0.1V
* @Date: 2018/7/23
* @Description: 路由限流枚举
**/
public enum ZuulRouteEnum {
/**
* 路由枚举
*/
ZUUL_ROUTE_LIST("zuul:route:list");
@Getter
@Setter
private String key;
ZuulRouteEnum(String key) {
this.key = key;
}
public static ZuulRouteEnum get(String key) {
for (ZuulRouteEnum c : ZuulRouteEnum.values()) {
if (c.key == key) {
return c;
}
}
return null;
}
}
路由参数
import lombok.Data;
/**
* @Author: 凉白开不加冰
* @Version: 0.0.1V
* @Date: 2018/7/23
* @Description: 路由参数
**/
@Data
public class ZuulRouteVO {
/**
* id主键
*/
private String id;
/**
* 网关路由访问地址
*/
private String path;
/**
* 服务地址
**/
private String url;
/**
* 服务id
*/
private String serviceId;
/**
* 是否启用 true启用 false不启用
*/
private Boolean enabled;
}
redis工具类
import com.alibaba.fastjson.JSON;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.util.List;
/**
* @Author: 凉白开不加冰
* @Version: 0.0.1V
* @Date: 2018/11/20
* @Description: redis工具类
**/
public class RedisTools {
public static <T> List<T> hget(StringRedisTemplate stringRedisTemplate,String key,Class<T> clazz){
List<Object> list = stringRedisTemplate.opsForHash().values(key);
return JSON.parseArray(list.toString(), clazz);
}
public static void hset(StringRedisTemplate stringRedisTemplate,String h,String key,String value){
stringRedisTemplate.opsForHash().put(h,key,value);
}
public static Boolean existsHash(StringRedisTemplate stringRedisTemplate,String h,String key){
return stringRedisTemplate.opsForHash().hasKey(h,key);
}
}
服务启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@EnableZuulProxy
@EnableDiscoveryClient
@SpringBootApplication
public class MicromserviceZuulApplication {
public static void main(String[] args) {
SpringApplication.run(MicromserviceZuulApplication.class, args);
}
}
路由刷新接口
/**
* @Author: 凉白开不加冰
* @Version: 0.0.1V
* @Date: 2018/7/23
* @Description: 刷新路由
**/
public interface RefreshRouteService {
/**
* @Author: 胡成
* @Date: 2018/7/23 16:35
* @Description: 刷新路由
**/
void refreshRoute();
}
路由刷新实现类
import com.example.service.RefreshRouteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.RoutesRefreshedEvent;
import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
/**
* @Author: 凉白开不加冰
* @Version: 0.0.1V
* @Date: 2018/7/23
* @Description: 路由刷新业务
**/
@Service
public class RefreshRouteServiceImpl implements RefreshRouteService {
@Autowired
private ApplicationEventPublisher publisher;
@Autowired
private RouteLocator routeLocator;
@Override
public void refreshRoute() {
RoutesRefreshedEvent routesRefreshedEvent = new RoutesRefreshedEvent(routeLocator);
publisher.publishEvent(routesRefreshedEvent);
}
}
第五步:redis中存放路由信息
{
"id": "test",
"serviceId": "",
"path": "/order/**",
"url": "http://192.168.0.111:9092",
"enabled": true
}