Gateway高可用集群与动态网关

1|基于Nginx部署GeteWay集群

网关集群可以通过Nginx与lvs实现,这里基于Nginx,实现比较简单。为nginx添加如下配置即可

upstream gateways {
	server 127.0.0.1:81;
	server 127.0.0.1:82;
}

server {
	listen       80;
	server_name  localhost;
	logs/host.access.log  main;

...

	location / {
		proxy_pass http://gateways/;
	}
	...
}

2|0动态网关

任何配置不用重启网关服务器都可以实现及时刷新网关配置。

实现方式:

  1. 分布式配置中心,不推荐
  2. 数据库,推荐,阅读性好

根据路由的相关配置,我们设计数据库表结构


CREATE TABLE `gateway_route`  (
   `id` int(11) primary key,
  `route_id` varchar(255) DEFAULT NULL,#路由id
  `route_name` varchar(255) DEFAULT NULL,
  `route_pattern` varchar(255) DEFAULT NULL,#路径匹配规则
  `route_type` varchar(255) DEFAULT NULL,#跳转类型,0时从注册中心获取地址,1直接跳转网络地址
  `route_uri` varchar(255) DEFAULT NULL #与route_type相对应的地址
)

插入如下的路由信息,member-service是注册中心上的服务,可替换成自己的

Gateway高可用集群与动态网关_第1张图片

根据数据库设计实体类

public class GateWayEntity {
    private Long id;
    private String routeId;
    private String routeName;
    private String routeType;
    private String routeUri;
    private String routePattern;
   ...
}

因为要从数据库获取路由信息,这里使用mybatis来访问数据库,接口如下

 
@Mapper
public interface GatewayRouteMapper {
	//获取全部路由
    List getAllRoutes();
}

对应xml如下

 

    
    
    
    
    
    


重点便是加载路由信息了,创建一个类实现ApplicationEventPublisherAware接口

@Service
public class GatewayService implements ApplicationEventPublisherAware {

    private ApplicationEventPublisher publisher;

    @Autowired
    private RouteDefinitionWriter routeDefinitionWriter;

    @Autowired
    private GatewayRouteMapper gatewayRouteMapper;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.publisher = applicationEventPublisher;
    }


    //从数据库获取全部路由,在将每个路由加载
    public void getAllRoutes() {
        List routes = gatewayRouteMapper.getAllRoutes();
        for (GateWayEntity route : routes) {
            loadRoute(route);
        }
    }
	//根据实体类加载路由
    public String loadRoute(GateWayEntity gateWayEntity) {
        //路由相关的配置
        RouteDefinition routeDefinition = new RouteDefinition();
        PredicateDefinition predicateDefinition = new PredicateDefinition();
        FilterDefinition filterDefinition = new FilterDefinition();

        Map predicateParams = new HashMap<>(8);

        URI uri = null;
        //根据路由类型来决定如何跳转
        if ("0".equals(gateWayEntity.getRouteType())) {
            uri  = UriComponentsBuilder.fromUriString("lb://"+gateWayEntity.getRouteUri()+"/").build().toUri();
        } else {
            uri = UriComponentsBuilder.fromHttpUrl(gateWayEntity.getRouteUri()).build().toUri();
        }



        //路由唯一id
        routeDefinition.setId(gateWayEntity.getRouteId());
        predicateDefinition.setName("Path");
        //路由转发地址
        predicateParams.put("pattern",gateWayEntity.getRoutePattern());
        predicateDefinition.setArgs(predicateParams);


        routeDefinition.setPredicates(Arrays.asList(predicateDefinition));
        routeDefinition.setUri(uri);

        routeDefinitionWriter.save(Mono.just(routeDefinition)).subscribe();

        this.publisher.publishEvent(new RefreshRoutesEvent(this));
        return "seccess";
    }

每次路由更改时,只要访问一下数据库,将路由信息加载即可。书写一个controller,调用一下service的getAllRoutes方法加载路由。

@RestController
public class GateWayController {

    @Autowired
    private GatewayService gatewayService;

    @GetMapping("/load")
    public String loadRoutes() {
        gatewayService.getAllRoutes();
        return "success";
    }

}

访问一下/load路径加载路由信息,在route_pattern匹配的路径就能访问了,每次修改数据库的路由信息后,只要重新加载,就能够实现动态网关服务。

转载地址:https://www.cnblogs.com/ylcc-zyq/p/13156526.html?ivk_sa=1024320u

你可能感兴趣的:(转载,geteway)