概述
网关的核心功能
动态路由
灰度发布
授权认证
性能监控
系统日志
数据缓存
限流熔断
目前业内的技术方案
Zuul
基于Java开发,核心网关功能都比较简单,但是比如灰度发布、限流、动态路由之类的,很多都要自己做二次开发
高并发能力不强,部署到一些机器上去,还要基于Tomcat来部署,Spring Boot用Tomcat把网关系统跑起来;Java语言开发,可以直接把控源码,可以做二次开发封装各种需要的功能
Kong
依托于Nginx实现,OpenResty,lua实现的模块,现成的一些插件,可以直接使用
Nginx+lua、自研网关
Nginx抗高并发的能力很强,少数几台机器部署一下,就可以抗很高的并发
动态路由
一般新增 修改 网关需要重启服务让网关生效,那会很麻烦,生产环境绝对不能这么做
可以基于二次开发,重写刷新网关路由配置
可以简单弄一个web项目
对配置的网关弄一个增删改查的功能
如果开发某个服务之后,可以在这个功能里面配置一下
表设计
CREATE TABLE `gateway_api_route` (
`id` varchar(50) NOT NULL,
`path` varchar(255) NOT NULL,
`service_id` varchar(50) DEFAULT NULL,
`url` varchar(255) DEFAULT NULL,
`retryable` tinyint(1) DEFAULT NULL,
`enabled` tinyint(1) NOT NULL,
`strip_prefix` int(11) DEFAULT NULL,
`api_name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
INSERT INTO gateway_api_route (id, path, service_id, retryable, strip_prefix, url, enabled) VALUES ('order-service', '/order/**', 'order-service',0,1, NULL, 1);
核心代码
@Configuration
public class DynamicRouteConfiguration {
@Autowired
private ZuulProperties zuulProperties;
@Autowired
private ServerProperties server;
@Autowired
private JdbcTemplate jdbcTemplate;
@Bean
public DynamicRouteLocator routeLocator() {
DynamicRouteLocator routeLocator = new DynamicRouteLocator(
this.server.getServletPrefix(), this.zuulProperties);
routeLocator.setJdbcTemplate(jdbcTemplate);
return routeLocator;
}
}
----
public class DynamicRouteLocator extends SimpleRouteLocator implements RefreshableRouteLocator {
private JdbcTemplate jdbcTemplate;
private ZuulProperties properties;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public DynamicRouteLocator(String servletPath, ZuulProperties properties) {
super(servletPath, properties);
this.properties = properties;
}
@Override
public void refresh() {
doRefresh();
}
@Override
protected Map<String, ZuulProperties.ZuulRoute> locateRoutes() {
LinkedHashMap<String, ZuulProperties.ZuulRoute> routesMap = new LinkedHashMap<>();
// 加载application.yml中的路由表
routesMap.putAll(super.locateRoutes());
// 加载db中的路由表
routesMap.putAll(locateRoutesFromDB());
// 统一处理一下路由path的格式
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());
}
System.out.println("路由表:" + values);
return values;
}
private Map<String, ZuulProperties.ZuulRoute> locateRoutesFromDB() {
Map<String, ZuulProperties.ZuulRoute> routes = new LinkedHashMap<>();
List<GatewayApiRoute> results = jdbcTemplate.query(
"select * from gateway_api_route where enabled = true ",
new BeanPropertyRowMapper<>(GatewayApiRoute.class));
for (GatewayApiRoute result : results) {
if (StringUtils.isEmpty(result.getPath()) ) {
continue;
}
if (StringUtils.isEmpty(result.getServiceId()) && StringUtils.isEmpty(result.getUrl())) {
continue;
}
ZuulProperties.ZuulRoute zuulRoute = new ZuulProperties.ZuulRoute();
try {
BeanUtils.copyProperties(result, zuulRoute);
} catch (Exception e) {
e.printStackTrace();
}
routes.put(zuulRoute.getPath(), zuulRoute);
}
return routes;
}
}
---
public class GatewayApiRoute {
private String id;
private String path;
private String serviceId;
private String url;
private boolean stripPrefix = true;
private Boolean retryable;
private Boolean enabled;
}
---
@Component
@Configuration
@EnableScheduling
public class RefreshRouteTask {
@Autowired
private ApplicationEventPublisher publisher;
@Autowired
private RouteLocator routeLocator;
@Scheduled(fixedRate = 5000)
private void refreshRoute() {
System.out.println("定时刷新路由表");
RoutesRefreshedEvent routesRefreshedEvent = new RoutesRefreshedEvent(routeLocator);
publisher.publishEvent(routesRefreshedEvent);
}
}
---
@SpringBootApplication
@EnableZuulProxy
public class ZuulGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulGatewayApplication.class, args);
}
}
如果网关需要抗每秒10万的高并发访问,你应该怎么对网关进行生产优化
eureka:每台机器都是对等的,都会有高并发请求,有瓶颈
zookeeper:服务上下线,全量通知其他服务,网络带宽被打满,有瓶颈
可以自研分布式服务注册中心:分片存储服务注册表,横向扩容,每台机器均摊高并发请求,各个服务主动拉取,避免反向通知网卡被打满
最后
以上就是活力硬币为你收集整理的分布式篇:网关的全部内容,希望文章能够帮你解决分布式篇:网关所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复