网关的核心功能
动态路由
灰度发布
授权认证
性能监控
系统日志
数据缓存
限流熔断
目前业内的技术方案
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=utf8INSERT INTO gateway_api_route (id, path, service_id, retryable, strip_prefix, url, enabled) VALUES ('order-service', '/order/**', 'order-service',0,1, NULL, 1);核心代码@Configurationpublic class DynamicRouteConfiguration {@Autowiredprivate ZuulProperties zuulProperties;@Autowiredprivate ServerProperties server;@Autowiredprivate JdbcTemplate jdbcTemplate;@Beanpublic 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;}@Overridepublic void refresh() {doRefresh();}@Overrideprotected 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 {@Autowiredprivate ApplicationEventPublisher publisher;@Autowiredprivate RouteLocator routeLocator;@Scheduled(fixedRate = 5000) private void refreshRoute() {System.out.println("定时刷新路由表"); RoutesRefreshedEvent routesRefreshedEvent = new RoutesRefreshedEvent(routeLocator);publisher.publishEvent(routesRefreshedEvent);}}---@SpringBootApplication@EnableZuulProxypublic class ZuulGatewayApplication {public static void main(String[] args) {SpringApplication.run(ZuulGatewayApplication.class, args);}}
如果网关需要抗每秒10万的高并发访问,你应该怎么对网关进行生产优化
eureka:每台机器都是对等的,都会有高并发请求,有瓶颈
zookeeper:服务上下线,全量通知其他服务,网络带宽被打满,有瓶颈
可以自研分布式服务注册中心:分片存储服务注册表,横向扩容,每台机器均摊高并发请求,各个服务主动拉取,避免反向通知网卡被打满