/** * * <pre> * 如果通过配置dubbo.service.shutdown.wait=20000(默认10000,10秒)这种方式, * k8s.terminationGracePeriodSeconds=缩小时间间隔, * 则会有线上的在途服务突然中断或者其他错误, * * 借助k8s的容器层的preStop来做灰度下线,并不影响线上服务, * * a. 先让nacos服务主动下线, * b. 然后等待一段时间再关闭容器(尽量是5秒以上), * c. 设置nacos的心跳超时(可选) * * 主动下线方法中,1调nacos实例下线(no run),2.调nacos的超时(仅在springcloud服务中能和),3.调dubbo的hoop shutdown接口 * 最后选择用3.dubbo的shutdown接口 * * 不能做到绝对的灰度 * * </pre> * * @param map * @return 成功标记 */ public boolean nacosDown(Map map) { String serviceName = nacosdiscoveryProperties.getService(); String groupName = nacosdiscoveryProperties.getGroup(); String clusterName = nacosdiscoveryProperties.getClusterName(); String server = nacosdiscoveryProperties.getServerAddr(); String ip = nacosdiscoveryProperties.getIp(); int port = nacosdiscoveryProperties.getPort(); log.info("nacosDown deregister from nacos, serviceName:{}, groupName:{}, clusterName:{}, server:{}, ip:{}, port:{} ", serviceName, groupName, clusterName, server, ip, port); try { //由于它会比terminationGracePeriodSeconds先执行,所以如果立刻下线的话新的pods还没开好的话, //a. 先让nacos服务主动下线, // dubboShutdownHook.destroyAll(); //b. 然后等待一段时间再关闭容器(尽量是5秒以上), Thread.sleep(waitTime * 1000); //c. 设置nacos的心跳超时(可选) nacosSetTimeout(nacosdiscoveryProperties); log.info("nacosDown sucess deregister from nacos, serviceName:{}, clusterName:{}, ip:{}, port:{}", serviceName, clusterName, ip, port); } catch (Exception e) { e.printstacktrace(); } log.info("nacosDown deregister from nacos, serviceName:{}, groupName:{}, clusterName:{}, server:{}, ip:{}, port:{} ", serviceName, groupName, clusterName, server, ip, port); return true; } /** * c. 设置nacos的心跳超时(可选) * @param nacosdiscoveryProperties */ private void nacosSetTimeout(NacosdiscoveryProperties nacosdiscoveryProperties) { String serviceName = nacosdiscoveryProperties.getService(); String clusterName = nacosdiscoveryProperties.getClusterName(); String server = nacosdiscoveryProperties.getServerAddr(); String ip = nacosdiscoveryProperties.getIp(); int port = nacosdiscoveryProperties.getPort(); String nameSpace = nacosdiscoveryProperties.getNamespace(); String[] split = server.split(","); JSONObject variables = new JSONObject(); variables.put("namespaceId", nameSpace); variables.put("serviceName", serviceName); JSONArray instantsList = new JSONArray(); //实例ip JSONObject instantsOne = new JSONObject(); instantsOne.put("ip", ip); instantsOne.put("port", port); instantsOne.put("clusterName", clusterName); instantsList.add(instantsOne); variables.put("instances", instantsList.toJSONString()); JSONObject MetaDataOne = new JSONObject(); MetaDataOne.put(PreservedMetadataKeys.HEART_BEAT_INTERVAL, "1000"); // 设置心跳超时时间,单位为秒,这里将心跳超时时间设为500毫秒 // 即服务端6秒收不到客户端心跳,会将该客户端注册的实例设为不健康: MetaDataOne.put(PreservedMetadataKeys.HEART_BEAT_TIMEOUT, "500"); // 设置实例删除的超时时间,单位为秒,这里将实例删除超时时间设为500毫秒, // 即服务端9秒收不到客户端心跳,会将该客户端注册的实例删除: MetaDataOne.put(PreservedMetadataKeys.IP_DELETE_TIMEOUT, "500"); variables.put("Metadata", MetaDataOne.toJSONString()); nacosMetaUrl = split[0] + nacosMetaUrl; if (variables != null) { nacosMetaUrl = nacosMetaUrl + "?" + asurlvariables(variables); } log.info("nacosDown rest , nacosMetaUrl:{} ", nacosMetaUrl); JSONObject result = RestUtil.put(nacosMetaUrl); log.info("nacosDown rest ok , nacosMetaUrl:{}, result:{} ", nacosMetaUrl, result.toJSONString()); } public static String asurlvariables(JSONObject variables) { Map<String, Object> source = variables.getInnerMap(); Iterator<String> it = source.keySet().iterator(); StringBuilder urlvariables; String key; String value; for(urlvariables = new StringBuilder(); it.hasNext(); urlvariables.append("&").append(key).append("=").append(value)) { key = (String)it.next(); value = ""; Object object = source.get(key); if (object != null && !StrUtil.isEmpty(object.toString())) { value = object.toString(); } } return urlvariables.substring(1); }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。