一、创建工程,在pom中引入Zuul

二、重写路由加载类,实在路由的动态注册和路由转发

package com.genius.gateway.zuul;

import com.genius.gateway.helper.DbHelper;
import com.genius.gateway.model.ZuulRouteKV;
import org.springframework.cloud.netflix.zuul.filters.RefreshableRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.Route;
import org.springframework.cloud.netflix.zuul.filters.SimpleRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random; import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.StringUtils; public class CustomRouteLocator extends SimpleRouteLocator implements RefreshableRouteLocator { public final static Logger logger=LoggerFactory.getLogger(CustomRouteLocator.class); private JdbcTemplate jdbcTemplate;
private DbHelper dbHelper;
public void setDbHelper(DbHelper dbHelper){
this.dbHelper=dbHelper;
} private ZuulProperties properties; //设置数据库连接
public void setJdbcTemplate(JdbcTemplate jdbcTemplate){
this.jdbcTemplate=jdbcTemplate;
} public CustomRouteLocator(String servletPah,ZuulProperties properties){
super(servletPah,properties);
this.properties=properties;
logger.info("servletPath:{}",servletPah);
} @Override
public void refresh() {
doRefresh();
} /**
*加载路由规则
*/
@Override
protected Map<String,ZuulProperties.ZuulRoute> locateRoutes(){
LinkedHashMap<String,ZuulProperties.ZuulRoute> routesMap=new LinkedHashMap<String,ZuulProperties.ZuulRoute>();
//从application.properties中加载路由信息
routesMap.putAll(super.locateRoutes());
//从db中加载路由信息
routesMap.putAll(locateRoutesFromDB());
//优化一下配置
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;
} /*
* 加载路由数据
* */
private Map<String,ZuulProperties.ZuulRoute> locateRoutesFromDB(){
Map<String,ZuulProperties.ZuulRoute> routes=new LinkedHashMap<>();
System.out.println("=============load zuul route info from db ==============");
//从数据库中加载数据
String sql="select t.*, t.rowid from PIPECLOUD.ZUULROUTE t where t.enabled=1";
sql="select * from zuulroute where enabled=true";
List<ZuulRouteKV> result=jdbcTemplate.query(sql,new BeanPropertyRowMapper<>(ZuulRouteKV.class));
//List<ZuulRouteKV> result= dbHelper.GetRoutesData();
//遍历数据
for(ZuulRouteKV item:result){
if(org.apache.commons.lang3.StringUtils.isBlank(item.getPath()) || org.apache.commons.lang3.StringUtils.isBlank(item.getUrl()) ){
continue;
}
ZuulProperties.ZuulRoute zuulRoute = new ZuulProperties.ZuulRoute();
try {
//org.springframework.beans.BeanUtils.copyProperties(result,zuulRoute);
zuulRoute.setId(item.getId());
zuulRoute.setPath(item.getPath());
zuulRoute.setServiceId(item.getServiceId());
zuulRoute.setStripPrefix(item.isStripPrefix());
zuulRoute.setUrl(item.getUrl());
} catch (Exception e) {
logger.error("=============load zuul route info from db with error==============",e);
}
routes.put(zuulRoute.getPath(),zuulRoute);
}
return routes;
} /**
* 获取路由
*/
@Override
protected Route getRoute(ZuulProperties.ZuulRoute route, String path) {
if (route == null) {
return null;
} else {
String targetPath = path;
String prefix = this.properties.getPrefix();
if (prefix.endsWith("/")) {
prefix = prefix.substring(0, prefix.length() - 1);
} if (path.startsWith(prefix + "/") && this.properties.isStripPrefix()) {
targetPath = path.substring(prefix.length());
} if (route.isStripPrefix()) { //源码
// int index = route.getPath().indexOf("*") - 1;
// if (index > 0) {
// String routePrefix = route.getPath().substring(0, index);
// targetPath = targetPath.replaceFirst(routePrefix, "");
// prefix = prefix + routePrefix;
// } //重构方法
int spliccount=route.getPath().split("/").length-1;
if(spliccount>0){
String[] paths=targetPath.split("/");
String indexStr=paths[spliccount]+"/";
int index1=targetPath.indexOf(indexStr)-1;
if(index1>0){
prefix=targetPath.substring(0,index1);
targetPath=targetPath.substring(index1);
}
} } Boolean retryable = this.properties.getRetryable();
if (route.getRetryable() != null) {
retryable = route.getRetryable();
} //负载均衡
String hostStr=route.getUrl();
String Location=hostStr;
String[] hosts=hostStr.split(";");
if(hosts.length>1){
Random random=new Random();
int index=random.nextInt(hosts.length);
Location=hosts[index];
} return new Route(route.getId(), targetPath, Location, prefix, retryable, route.isCustomSensitiveHeaders() ? route.getSensitiveHeaders() : null, route.isStripPrefix());
}
}
}
@Configuration
public class CustomZuulConfig { @Autowired
ZuulProperties zuulProperties;
@Autowired
ServerProperties server;
@Autowired
JdbcTemplate jdbcTemplate; //@Autowired
//DbHelper dbHelper; @Bean
public CustomRouteLocator routeLocator(){
String path=this.server.getServlet().getServletPrefix();
CustomRouteLocator reouteLocator=new CustomRouteLocator(path, this.zuulProperties);
reouteLocator.setJdbcTemplate(jdbcTemplate);
//reouteLocator.setDbHelper(dbHelper);
return reouteLocator;
}
}
@Service
public class RefreshRouteService { @Autowired
ApplicationEventPublisher publisher; @Autowired
RouteLocator routeLocator; //刷新路由配置信息
public void refreshRoute() {
RoutesRefreshedEvent routesRefreshedEvent = new RoutesRefreshedEvent(routeLocator);
publisher.publishEvent(routesRefreshedEvent);
}
}
@RestController
@RequestMapping("/admin")
public class AdminController { @RequestMapping("/index")
public String index(){
return "index";
} @Autowired
RefreshRouteService server; @RequestMapping("/refreshRoute")
public String refreshRoute(){
server.refreshRoute();
return "路由重置成功!";
}
}

三、跨域请求过滤器

/**
* 实现跨域请求
* #防止header重复写入
* zuul.sensitive-headers=Access-Control-Allow-Origin,Access-Control-Allow-Method
*/
@Configuration
public class GateWayCorsConfig {
@Bean
public FilterRegistrationBean corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
//这个请求头在https中会出现,但是有点问题,下面我会说
//config.addExposedHeader("X-forwared-port, X-forwarded-host");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return bean;
}
}

https://blog.csdn.net/tianyaleixiaowu/article/details/77933295?locationNum=5&fps=1

https://www.cnblogs.com/sam-uncle/p/9011400.html

SpringCloud-Zuul搭建的更多相关文章

  1. SpringCLoud之搭建Zuul网关集群

    1.使用技术 Springboot,SpringCloud,Zuul,Nignx 2.目的 使用Zuul搭建微服务高可用的网关 3.项目创建 3.1 创建注册中心(略) 3.2 创建一个hello-s ...

  2. SpringCloud Zuul网关超时

    最近在使用SpringCloudZuul网关时,报错"NUMBEROF_RETRIES_NEXTSERVER_EXCEEDED", 查询资料后,发现: ribbon.Connect ...

  3. springcloud Zuul学习笔记

    SpringCloud Zull是一个基于NetflixZuul实现的API网关组件,它实现了请求路由,负载均衡,校验过滤等功能;本文主要记录springcloud zuul的入门级demo开发过程; ...

  4. 「开源」SpringCloud+vue搭建的商城项目

    最近在研究SpringCloud,看到一个基于SpringCloud+vue搭建的模拟商城项目.用来辅助学习SpringCloud企业级开发还是很有帮助的.强烈推荐!! 源码地址在最后. spring ...

  5. spring-cloud项目搭建

    springCloud项目搭建手册 springcloud应用场景及微服务框架发展趋势 Spring Cloud为开发人员提供了工具,以快速构建分布式系统中的某些常见模式(例如,配置管理,服务发现,断 ...

  6. springcloud第五步:使用Zuul搭建服务接口网关

    路由网关(zuul) 什么是网关 Zuul的主要功能是路由转发和过滤器.路由功能是微服务的一部分,比如/api/user转发到到user服务,/api/shop转发到到shop服务.zuul默认和Ri ...

  7. Springcloud config + zuul 搭建动态网关

    1,实现的效果,就是zuul 网关的配置路由实现负载均衡,zuul 的配置文件放在springcloud config 上 2,需要的服务如下: 3,其实就是配置下springcloud-zuul 的 ...

  8. SpringCloud Zuul网关的简单理解

    Zuul网关功能 请求路由.服务路由.请求过滤 请求路由 参数配置如下所示,所有能够配置path规则的请求,都会被zuul网关转发到对应的url上. zuul.routes.user-service. ...

  9. 使用springcloud gateway搭建网关(分流,限流,熔断)

    Spring Cloud Gateway Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 ...

  10. springcloud zuul

    zuul是springcloud的API网关. 入口也是springmvc的DispatcherServlet. 实际的handler是ZuulController,通过handleRequest方法 ...

随机推荐

  1. undefined&nbsp;reference&nbsp;to…

    照着GUN/Linux编程指南中的一个例子输入编译,结果出现如下错误: undefined reference to 'pthread_create' undefined reference to ' ...

  2. C51串口的SCON寄存器及工作…

    原文地址:C51串口的SCON寄存器及工作方式作者:batistar 一,串行口控制寄存器SCON 它用于定义串行口的工作方式及实施接收和发送控制.字节地址为98H,其各位定义如下表: D7 D6 D ...

  3. sftp put权限不够

    报错如下: sftp> put play.zip ./ Uploading play.zip to /opt/library/./play.zip remote open("/opt/ ...

  4. mysql日期获取

    获取当前日期在本周的周一:select subdate(curdate(),date_format(curdate(),'%w')-1) 获取当前日期在本周的周日:select subdate(cur ...

  5. 用rand5()生成rand(n)

    问题:有函数rand5(),它能够等概率生成[0,5)之间的整数.由rand5()构造rand(n)使其能够等概率生成[0,n)之间的整数. 思路1:有rand5()先生成等概率生成0和1的rand0 ...

  6. linux设置rsync+inotify实时同步文件

    linux设置rsync+inotify实时同步文件   应用场景: 同步接收方:test01 接收目录:/opt/software/test/a/ 同步发起方:test02 同步目录:/opt/so ...

  7. Android selector中的item的顺序

    在selector中,要将默认状态的item放在最后面,因为一旦前面的item满足匹配条件,后面的item就不会去匹配.因此,把默认状态的item放在前面的话,后面的item没有执行的机会

  8. while循环for循环优缺点和应用

    while循环常用于那种不知道循环次数是多少的情况,比如让用户循环输入一个整数,直到输入某个特殊的字符为止,你根本没法直到这个循环会进行的次数. for循环多用于循环次数比较明确的情况,比如for(n ...

  9. java日期和时间转换字符

    日期和时间转换字符 字符 描述 例子 c 完整的日期和时间 Mon May 04 09:51:52 CDT 2009 F ISO 8601 格式日期 2004-02-09 D U.S. 格式日期 (月 ...

  10. export default {} 和new Vue()区别

     1.export default 的用法:相当于提供一个接口给外界,让其他文件通过 import 来引入使用. 而对于export default 和export的区别:  在JavaScript ...