package com.sf.vertx.handle; import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.lang3.StringUtils; import org.springframework.data.redis.core.RedisTemplate; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.TypeReference; import com.hazelcast.config.Config; import com.hazelcast.config.JoinConfig; import com.hazelcast.config.NetworkConfig; import com.hazelcast.config.TcpIpConfig; import com.sf.vertx.api.pojo.ApiConfig; import com.sf.vertx.api.pojo.AppConfig; import com.sf.vertx.api.pojo.DataSecurity; import com.sf.vertx.api.pojo.Node; import com.sf.vertx.api.pojo.RouteContent; import com.sf.vertx.api.pojo.SacService; import com.sf.vertx.api.pojo.Strategy; import com.sf.vertx.api.pojo.VertxConfig; import com.sf.vertx.arithmetic.roundRobin.SacLoadBalancing; import com.sf.vertx.constans.RedisKeyConfig; import com.sf.vertx.enums.GatewayServiceType; import com.sf.vertx.httpproxy.HttpProxy; import com.sf.vertx.init.SacVertxConfig; import com.sf.vertx.pojo.ClusterEventMsg; import com.sf.vertx.pojo.SacCircuitBreaker; import com.sf.vertx.pojo.SacCurrentLimiting; import com.sf.vertx.security.MainSecurity; import com.sf.vertx.utils.ProxyTool; import cn.hutool.core.collection.ConcurrentHashSet; import io.github.resilience4j.ratelimiter.RateLimiterConfig; import io.github.resilience4j.ratelimiter.RateLimiterRegistry; import io.vertx.circuitbreaker.CircuitBreaker; import io.vertx.circuitbreaker.CircuitBreakerOptions; import io.vertx.core.Future; import io.vertx.core.Vertx; import io.vertx.core.VertxOptions; import io.vertx.core.http.HttpClient; import io.vertx.core.http.HttpServer; import io.vertx.core.http.HttpServerOptions; import io.vertx.core.net.JksOptions; import io.vertx.core.spi.cluster.ClusterManager; import io.vertx.ext.web.Route; import io.vertx.ext.web.Router; import io.vertx.ext.web.client.WebClient; import io.vertx.ext.web.handler.CorsHandler; import io.vertx.ext.web.handler.HttpException; import io.vertx.httpproxy.ProxyContext; import io.vertx.httpproxy.ProxyInterceptor; import io.vertx.httpproxy.ProxyResponse; import io.vertx.spi.cluster.hazelcast.HazelcastClusterManager; import lombok.extern.slf4j.Slf4j; /*** * vertx配置维护 * * @author xy * */ @Slf4j public class AppConfigHandler { private static VertxConfig VERTX_CONFIG = new VertxConfig(); public static Vertx VERTX; private static SacVertxConfig sacVertxConfig; private static RedisTemplate redisTemplate; private static final ConcurrentHashMap CACHE_APP_CONFIG_MAP = new ConcurrentHashMap<>(); // global api config appCode - RateLimiterRegistry private static final ConcurrentHashMap GLOBAL_API_CURRENT_LIMITING_MAP = new ConcurrentHashMap<>(); // global app config appCode - Strategy private static final ConcurrentHashMap GLOBAL_APP_CURRENT_LIMITING_MAP = new ConcurrentHashMap<>(); // appCode:apiCode:SacLoadBalancing private static ConcurrentHashMap LOADBALANCING_MAP = new ConcurrentHashMap<>(); // appCode:apiCode - ApiConfig private static ConcurrentHashMap APICODE_CONFIG_MAP = new ConcurrentHashMap<>(); // apiCode限流配置 appCode:apiCode - RateLimiterRegistry private static ConcurrentHashMap APICODE_CONFIG_CURRENT_LIMITING_MAP = new ConcurrentHashMap<>(); // 服务类型, apiCode限流配置 appCode:apiCode - 服务类型,SAC=SAC规范服务,OPEN=开放服务 private static ConcurrentHashMap APICODE_CONFIG_SERVICE_TYPE_MAP = new ConcurrentHashMap<>(); // 负载均衡路由类型 appCode:apiCode - routerType // 执行流程 routerType=
// 1、serviceNodel="NORMAL", serviceNodel="ROUTE" and RouteType = "WEIGHT_ROUTE" //
// return LOADBALANCING_MAP // 2、serviceNodel="ROUTE", RouteType = "HEADER_ROUTE"
// return APICODE_CONFIG_ROUTERCONENT_MAP private static ConcurrentHashMap APICODE_CONFIG_ROUTERTYPE_MAP = new ConcurrentHashMap<>(); private static ConcurrentHashMap> APICODE_CONFIG_HEADER_ROUTERCONENT_MAP = new ConcurrentHashMap<>(); // apiCode熔断配置 appCode:apiCode - CircuitBreaker private static ConcurrentHashMap APICODE_CONFIG_CIRCUIT_BREAKER_MAP = new ConcurrentHashMap<>(); // apicode uri = * - appConfig private static ConcurrentHashMap APICODE_APPCONFIG_MAP = new ConcurrentHashMap<>(); // 禁用appCode private static ConcurrentHashSet DISABLED_APPCODE = new ConcurrentHashSet(); public static AppConfig getAppConfigByDomain(String domain) { return APICODE_APPCONFIG_MAP.get(domain); } public static Integer routerType(String key) { return APICODE_CONFIG_ROUTERTYPE_MAP.get(key) != null ? APICODE_CONFIG_ROUTERTYPE_MAP.get(key) : 1; } public static List routerHeaderConentList(String key) { return APICODE_CONFIG_HEADER_ROUTERCONENT_MAP.get(key); } public static Boolean isServiceTypeOpen(String key) { return APICODE_CONFIG_SERVICE_TYPE_MAP.get(key) != null && StringUtils.equals(APICODE_CONFIG_SERVICE_TYPE_MAP.get(key), GatewayServiceType.OPEN.getCode()); } public static Boolean isServiceTypeSac(String key) { return APICODE_CONFIG_SERVICE_TYPE_MAP.get(key) != null && StringUtils.equals(APICODE_CONFIG_SERVICE_TYPE_MAP.get(key), GatewayServiceType.SAC.getCode()); } public static String getServiceType(String key) { return APICODE_CONFIG_SERVICE_TYPE_MAP.get(key); } public static String sacResponseHeaderKey() { return sacVertxConfig.getSacResponseHeaderKey(); } public static String rpcUri() { return sacVertxConfig.getRpcUri(); } public static void removeDisabledAppcode(String appCode) { DISABLED_APPCODE.remove(appCode); } public static void addDisabledAppcode(String appCode) { DISABLED_APPCODE.add(appCode); } public static boolean isDisabledAppcode(String appCode) { return DISABLED_APPCODE.contains(appCode); } public static SacCurrentLimiting getGlobalAppCurrentLimitingConfig(String appCode) { return GLOBAL_APP_CURRENT_LIMITING_MAP.get(appCode); } public static AppConfig getAppConfig(String appCode) { return CACHE_APP_CONFIG_MAP.get(appCode); } public static void init(RedisTemplate _redisTemplate, SacVertxConfig _sacVertxConfig) { redisTemplate = _redisTemplate; sacVertxConfig = _sacVertxConfig; } public static boolean isDataSecurity(String appCode) { return CACHE_APP_CONFIG_MAP.get(appCode) != null && CACHE_APP_CONFIG_MAP.get(appCode).getDataSecurity() != null; } public static boolean isApiCodeCircuitBreaker(String key) { return APICODE_CONFIG_CIRCUIT_BREAKER_MAP.get(key) != null; } public static SacCircuitBreaker getApiCodeCircuitBreaker(String key) { return APICODE_CONFIG_CIRCUIT_BREAKER_MAP.get(key); } /*** * 优先apicode配置限流、无法找到匹配全局限流 * * @param appCode * @param apiCode * @return */ public static SacCurrentLimiting getApiCurrentLimiting(String appCode, String apiCode) { String key = appCode + ":" + apiCode; SacCurrentLimiting sacCurrentLimiting = APICODE_CONFIG_CURRENT_LIMITING_MAP.get(key) != null ? APICODE_CONFIG_CURRENT_LIMITING_MAP.get(key) : null; sacCurrentLimiting = sacCurrentLimiting != null ? sacCurrentLimiting : (GLOBAL_API_CURRENT_LIMITING_MAP.get(appCode) != null ? GLOBAL_API_CURRENT_LIMITING_MAP.get(appCode) : null); return sacCurrentLimiting; } public static VertxConfig getVertxConfig() { return VERTX_CONFIG; } public static String getAppCodeHeaderKey() { return VERTX_CONFIG.getAppCodeHeaderKey(); } public static String getApiCodeHeaderKey() { return VERTX_CONFIG.getApiCodeHeaderKey(); } public static SacLoadBalancing getLoadBalancing(String key) { return LOADBALANCING_MAP.get(key); } public static ApiConfig getApicodeConfig(String key) { return APICODE_CONFIG_MAP.get(key); } public static Long getApicodeConfigTimeOut(String key) { return APICODE_CONFIG_MAP.get(key) != null ? APICODE_CONFIG_MAP.get(key).getTimeout() : 3000L; } private static RateLimiterRegistry createRateLimiter(Strategy strategy) { RateLimiterConfig config = RateLimiterConfig.custom() .limitRefreshPeriod(Duration.ofSeconds(strategy.getTimeWindow())) .limitForPeriod(strategy.getThreshold()).timeoutDuration(Duration.ofMillis(0)).build(); RateLimiterRegistry registry = RateLimiterRegistry.of(config); return registry; } private static void initRateLimiter(String appCode, Strategy strategy, ConcurrentHashMap map) { RateLimiterRegistry registry = createRateLimiter(strategy); SacCurrentLimiting sacCurrentLimiting = new SacCurrentLimiting(); sacCurrentLimiting.setStrategy(strategy); sacCurrentLimiting.setRegistry(registry); map.put(appCode, sacCurrentLimiting); } /*** * 从redis加载数据 * * @throws Exception */ public static void initAllAppConfig() { Set set = redisTemplate.opsForZSet().range(RedisKeyConfig.APP_CONFIG_SET_KEY, 0, -1); for (String appCode : set) { AppConfigHandler.initAppConfig(appCode, false); } } /*** * 加载vertx配置 */ public static void initVertxConfig() { String vertxConfigKey = RedisKeyConfig.VERTX_CONFIG_STRING_KEY; String vertxConfigValue = redisTemplate.opsForValue().get(vertxConfigKey); if (StringUtils.isNotBlank(vertxConfigValue)) { VERTX_CONFIG = JSONObject.parseObject(vertxConfigValue, VertxConfig.class); } } private static void delAppConfigCache(String appCode) { AppConfig appConfig = CACHE_APP_CONFIG_MAP.get(appCode); if (appConfig != null) { // app、api默认限流 GLOBAL_API_CURRENT_LIMITING_MAP.remove(appCode); GLOBAL_APP_CURRENT_LIMITING_MAP.remove(appCode); for (SacService sacService : appConfig.getService()) { if (sacService.getApiConfig() != null && sacService.getApiConfig().size() > 0) { for (ApiConfig apiConfig : sacService.getApiConfig()) { String key = appCode + ":" + apiConfig.getApiCode(); APICODE_CONFIG_MAP.remove(key); LOADBALANCING_MAP.remove(key); APICODE_CONFIG_SERVICE_TYPE_MAP.remove(key); APICODE_CONFIG_CURRENT_LIMITING_MAP.remove(key); APICODE_APPCONFIG_MAP.remove(apiConfig.getApiCode()); String keyCircuitBreaker = key + ":" + "CIRCUIT_BREAKER"; SacCircuitBreaker sacCircuitBreaker = APICODE_CONFIG_CIRCUIT_BREAKER_MAP.get(key); if (sacCircuitBreaker != null) { if(sacCircuitBreaker.getCircuitBreaker() != null) { sacCircuitBreaker.getCircuitBreaker().close(); } APICODE_CONFIG_CIRCUIT_BREAKER_MAP.remove(keyCircuitBreaker); } } } } // 应用配置 CACHE_APP_CONFIG_MAP.remove(appCode); } } public static void initAppConfig(String appCode, boolean isDelLocalCache) { // 是否需要先删除 if (isDelLocalCache) { delAppConfigCache(appCode); } String appCodeKey = RedisKeyConfig.APP_CONFIG_PREFIX_KEY + ":" + appCode; String appCodeValue = redisTemplate.opsForValue().get(appCodeKey); if (StringUtils.isNotBlank(appCodeValue)) { AppConfig appConfig = JSON.parseObject(appCodeValue, new TypeReference() { }); CACHE_APP_CONFIG_MAP.put(appCode, appConfig); // app、api默认限流 if (appConfig.getApiCurrentLimitingConfig() != null) { initRateLimiter(appCode, appConfig.getApiCurrentLimitingConfig(), GLOBAL_API_CURRENT_LIMITING_MAP); } if (appConfig.getAppCurrentLimitingConfig() != null) { initRateLimiter(appCode, appConfig.getAppCurrentLimitingConfig(), GLOBAL_APP_CURRENT_LIMITING_MAP); } // app router负载均衡 List routeContentList = null; for (SacService sacService : appConfig.getService()) { int routerType = 1; List nodeList = new ArrayList<>(); // 获取service模式 if (StringUtils.equals(sacService.getServiceModel(), "NORMAL")) { Node node = new Node(); node.setIp(sacService.getServerAddress().getHost()); node.setPort(sacService.getServerAddress().getPort()); node.setWeight(0); node.setProtocol(sacService.getServerAddress().getProtocol()); nodeList.add(node); } else if (StringUtils.equals(sacService.getServiceModel(), "ROUTE")) { if (sacService.getRouteConfig() != null && StringUtils.equals(sacService.getRouteConfig().getRouteType(), "WEIGHT_ROUTE")) { for (RouteContent routeContent : sacService.getRouteConfig().getRouteContent()) { Node node = new Node(); node.setIp(routeContent.getServerAddress().getHost()); node.setPort(routeContent.getServerAddress().getPort()); node.setWeight(routeContent.getWeight() != null && routeContent.getWeight() > 0 ? routeContent.getWeight() : 1); node.setProtocol(routeContent.getServerAddress().getProtocol()); nodeList.add(node); } } else if (sacService.getRouteConfig() != null && StringUtils.equals(sacService.getRouteConfig().getRouteType(), "HEADER_ROUTE")) { routerType = 2; routeContentList = sacService.getRouteConfig().getRouteContent(); } } // 初始化apiConfig if (sacService.getApiConfig() != null && sacService.getApiConfig().size() > 0) { for (ApiConfig apiConfig : sacService.getApiConfig()) { String key = appCode + ":" + apiConfig.getApiCode(); APICODE_CONFIG_MAP.put(key, apiConfig); if (sacService.getServiceType() != null) { APICODE_CONFIG_SERVICE_TYPE_MAP.put(key, sacService.getServiceType()); } // OPEN模式, 域名映射 if (isServiceTypeOpen(key)) { APICODE_APPCONFIG_MAP.put(apiConfig.getApiCode(), appConfig); } // 负载均衡模式 APICODE_CONFIG_ROUTERTYPE_MAP.put(key, routerType); switch (routerType) { case 1: if (nodeList.size() > 0) { // 初始化负载均衡算法 SacLoadBalancing sacLoadBalancing = ProxyTool.roundRobin(nodeList); LOADBALANCING_MAP.put(key, sacLoadBalancing); } break; case 2: APICODE_CONFIG_HEADER_ROUTERCONENT_MAP.put(key, routeContentList); default: break; } if (apiConfig.getStrategy() != null && apiConfig.getStrategy().size() > 0) { for (Strategy strategy : apiConfig.getStrategy()) { if (StringUtils.equals(strategy.getType(), "CURRENT_LIMITING")) { RateLimiterRegistry registry = createRateLimiter(strategy); SacCurrentLimiting sacCurrentLimiting = new SacCurrentLimiting(); sacCurrentLimiting.setStrategy(strategy); sacCurrentLimiting.setRegistry(registry); APICODE_CONFIG_CURRENT_LIMITING_MAP.put(key, sacCurrentLimiting); } else if (StringUtils.equals(strategy.getType(), "CIRCUIT_BREAKER")) { String keyCircuitBreaker = key + ":" + "CIRCUIT_BREAKER"; // interfaceBreaker = CircuitBreaker.create("interfaceBreaker", VERTX, // new CircuitBreakerOptions().setMaxFailures(3).setMaxRetries(5).setTimeout(2000) // .setFallbackOnFailure(true) // ).openHandler(v -> { // log.info("Circuit opened"); // }).closeHandler(v -> { // log.info("Circuit closed"); // });//.retryPolicy(retryCount -> retryCount * 100L); // apiCode熔断 CircuitBreaker circuitBreaker = CircuitBreaker .create(keyCircuitBreaker + "-circuit-breaker", VERTX, new CircuitBreakerOptions().setMaxFailures(strategy.getThreshold()) // 最大失败数 .setFailuresRollingWindow(strategy.getTimeWindow() * 1000) // 毫秒 // .setTimeout(apiConfig.getTimeout()) // 超时时间,不要开启, // 配置会设置接口超时, 这个参数有bug,半开超时会卡死 .setFallbackOnFailure(true) // 失败后是否调用回退函数(fallback) .setResetTimeout(strategy.getRecovery_interval() * 1000) // 在开启状态下,尝试重试之前所需时间 ).openHandler(v -> { log.info(keyCircuitBreaker + " Circuit open"); }).halfOpenHandler(v -> { log.info(keyCircuitBreaker + " Circuit halfOpen"); }).closeHandler(v -> { log.info(keyCircuitBreaker + " Circuit close"); }); SacCircuitBreaker sacCircuitBreaker = new SacCircuitBreaker(); sacCircuitBreaker.setCircuitBreaker(circuitBreaker); sacCircuitBreaker.setStrategy(strategy); APICODE_CONFIG_CIRCUIT_BREAKER_MAP.put(key, sacCircuitBreaker); } } } } } } } } public static void createVertx() { // TODO 编解码线程池,后面优化协程等方式 VertxOptions vertxOptions = new VertxOptions(); loadVertxOptions(vertxOptions); VERTX = Vertx.vertx(vertxOptions); createVertxRouter(); consumerClusterEventMsg(); } private static Config hazelcastConfig(SacVertxConfig sacVertxConfig) { // 集群 Config hazelcastConfig = new Config(); hazelcastConfig.setClusterName(sacVertxConfig.getClusterName()); // 集群名字 NetworkConfig networkConfig = new NetworkConfig(); networkConfig.setPort(sacVertxConfig.getNetworkPort()); networkConfig.setPortAutoIncrement(sacVertxConfig.isPortAutoIncrement()); JoinConfig join = new JoinConfig(); TcpIpConfig tcpIpConfig = new TcpIpConfig(); tcpIpConfig.setEnabled(true); String[] clusterIps = sacVertxConfig.getClusterIp().split(","); List members = Arrays.asList(clusterIps); tcpIpConfig.setMembers(members); join.setTcpIpConfig(tcpIpConfig); networkConfig.setJoin(join); hazelcastConfig.setNetworkConfig(networkConfig); // TODO 还有问题,不会使用 // ManagementCenterConfig managementCenterConfig = new ManagementCenterConfig(); // Set interfaces = new HashSet<>(); // interfaces.add("http://192.168.1.68:8080/mancenter"); // managementCenterConfig.setTrustedInterfaces(interfaces); // hazelcastConfig.setManagementCenterConfig(managementCenterConfig); return hazelcastConfig; } public static void createHazelcastClusterVertx() { Config hazelcastConfig = hazelcastConfig(sacVertxConfig); ClusterManager hazelcastClusterManager = new HazelcastClusterManager(hazelcastConfig); // TODO 编解码线程池,后面优化协程等方式 VertxOptions vertxOptions = new VertxOptions(); loadVertxOptions(vertxOptions); vertxOptions.setClusterManager(hazelcastClusterManager); Vertx.clusteredVertx(vertxOptions, res -> { if (res.succeeded()) { VERTX = res.result(); log.info("hazelcastClusterManager create success"); createVertxRouter(); consumerClusterEventMsg(); } else { res.cause().printStackTrace(); log.info("hazelcastClusterManager create failure"); } }); } private static void consumerClusterEventMsg() { // 订阅消息 VERTX.eventBus().consumer("sac_cluster_event", message -> { if (message.body() != null) { ClusterEventMsg msg = JSONObject.parseObject(message.body().toString(), ClusterEventMsg.class); log.info("Received message: {}", msg); // message.reply("我是返回数据===" + message.body()); if (msg.getType() == 1) { if (msg.getOperation() == 1) { // 初始化AppConfig本地缓存 AppConfigHandler.initAppConfig(msg.getAppCode(), true); } else if (msg.getOperation() == 3) { // 删除本地缓存 delAppConfigCache(msg.getAppCode()); } else if (msg.getOperation() == 4) { // 禁用app addDisabledAppcode(msg.getAppCode()); } else if (msg.getOperation() == 5) { // 启用app removeDisabledAppcode(msg.getAppCode()); } } } }); } /*** * 发布消息,订阅消息 * * @param msg */ public static void publishClusterEventMsg(ClusterEventMsg msg) { VERTX.eventBus().publish("sac_cluster_event", JSONObject.toJSONString(msg)); } private static void createVertxRouter() { // consul初始化 // ConsulHandler.init(vertx); // 从redis同步app配置 initAllAppConfig(); VertxConfig vertxConfig = AppConfigHandler.getVertxConfig(); // 创建HTTP监听 // 所有ip都能访问 HttpServerOptions httpServerOptions = new HttpServerOptions().setHost("0.0.0.0"); if (sacVertxConfig.isSSLs()) { httpServerOptions.setSsl(true) .setKeyStoreOptions(new JksOptions().setPassword("changeit").setPath("keystore.jks")); } HttpServer server = VERTX.createHttpServer(httpServerOptions); Router mainHttpRouter = Router.router(VERTX); Integer serverPort = vertxConfig.getPort() == null ? sacVertxConfig.getPort() : vertxConfig.getPort(); log.info("serverPort:{}", serverPort); server.requestHandler(mainHttpRouter).listen(serverPort, h -> { if (h.succeeded()) { log.info("HTTP端口监听成功:{}", serverPort); } else { log.error("HTTP端口监听失败:{}", serverPort); } }); HttpClient proxyClient = VERTX.createHttpClient(); HttpProxy proxy = HttpProxy.reverseProxy(proxyClient); proxy.originSelector(request -> Future.succeededFuture(ProxyTool.resolveOriginAddress(request))); proxy.addInterceptor(new ProxyInterceptor() { @Override public Future handleProxyRequest(ProxyContext context) { // if(StringUtils.equals(sacAppHeaderKey, "dsafdsfadafhappC")) { // // 会跳转到 RestfulFailureHandlerImpl // throw new HttpException(10003); // } return context.sendRequest(); } @Override public Future handleProxyResponse(ProxyContext context) { // 调试代码,获取reponse body // Filter filter = new Filter(); // ProxyResponse proxyResponse = context.response(); // Body body = proxyResponse.getBody(); // proxyResponse.setBody(Body.body(filter.init(context.request().getURI(), body.stream(), false))); // 继续拦截链 return context.sendResponse(); } }); WebClient mainWebClient = WebClient.create(VERTX); String rateLimitModel = vertxConfig.getRateLimitModel(); Route routeSac = mainHttpRouter.post(rpcUri()); routeSac.handler(CorsHandler.create().addRelativeOrigin(".*")) .handler(ParameterCheckHandler.create(GatewayServiceType.SAC)) .handler(AppRateLimitHandler.create(rateLimitModel)) .handler(ApiRateLimitHandler.create(rateLimitModel)) .handler(BodyPreCheckHandler.create()) .handler(BodyHandler.create().setHandleFileUploads(false)) .handler(BodyPostAnalysisHandler.create()) .handler(BodyPostCheckHandler.create()) .handler(SacRouteRequestHandler.create(mainWebClient)) .handler(ProxyHandler.create(mainWebClient, proxy)) .failureHandler(RestfulFailureHandler.create()); Route routeOpen = mainHttpRouter.route(); routeOpen.handler(CorsHandler.create().addRelativeOrigin(".*")) .handler(ParameterCheckHandler.create(GatewayServiceType.OPEN)) .handler(AppRateLimitHandler.create(rateLimitModel)) .handler(ApiRateLimitHandler.create(rateLimitModel)) .handler(BodyPreCheckHandler.create()) .handler(BodyHandler.create().setHandleFileUploads(false)) .handler(BodyPostCheckHandler.create()) .handler(SacRouteRequestHandler.create(mainWebClient)) .handler(ProxyHandler.create(mainWebClient, proxy)) .failureHandler(RestfulFailureHandler.create()); } private static void loadVertxOptions(VertxOptions vertxOptions) { long blockedThreadCheckInterval = VERTX_CONFIG.getVertxOptionsConfig() == null ? -1 : VERTX_CONFIG.getVertxOptionsConfig().getBlockedThreadCheckInterval(); int workerPoolSize = VERTX_CONFIG == null || VERTX_CONFIG.getVertxOptionsConfig() == null ? -1 : VERTX_CONFIG.getVertxOptionsConfig().getWorkerPoolSize(); if (workerPoolSize != -1) { vertxOptions.setWorkerPoolSize(workerPoolSize); } // TODO // blockedThreadCheckInterval = 1000000L; if (blockedThreadCheckInterval != -1) { vertxOptions.setBlockedThreadCheckInterval(blockedThreadCheckInterval); // 不打印Thread blocked 阻塞日志 } } public static String bodyEncrypt(String body, String appCode) { DataSecurity dataSecurity = getAppConfig(appCode).getDataSecurity(); switch (dataSecurity.getAlgorithm()) { case "AES": return MainSecurity.aesEncrypt(body, dataSecurity.getPrivateKey()); case "RSA": return MainSecurity.rsaEncrypt(body, dataSecurity.getPublicKey()); default: break; } log.info(" appCode:{}, encrypt key config is error.", appCode); throw new HttpException(10011); } public static String bodyDecrypt(String body, String appCode) { DataSecurity dataSecurity = getAppConfig(appCode).getDataSecurity(); switch (dataSecurity.getAlgorithm()) { case "AES": return MainSecurity.aesDecrypt(body, dataSecurity.getPrivateKey()); case "RSA": return MainSecurity.rsaDecrypt(body, dataSecurity.getPrivateKey()); default: break; } log.info(" appCode:{}, decrypt key config is error.", appCode); throw new HttpException(10011); } }