当前位置: 首页 > news >正文

江苏九天建设有限公司网站简述网站的设计流程是怎样的

江苏九天建设有限公司网站,简述网站的设计流程是怎样的,网站页面和图片设计,南京小程序开发网站制目录 1. 什么金丝雀发布#xff1f;它有什么用#xff1f; 2.如何实现全链路的金丝雀发布 2.1 负载均衡模块 2.2 网关模块 2.3 服务模块 2.3.1 注册为灰色服务实例 2.3.2 设置负载均衡器 2.3.3 传递灰度发布标签 2.4 其他代码 2.4.1 其他业务代码 2.4.2 pom.xml 关…目录 1. 什么金丝雀发布它有什么用 2.如何实现全链路的金丝雀发布 2.1 负载均衡模块 2.2 网关模块 2.3 服务模块 2.3.1 注册为灰色服务实例 2.3.2 设置负载均衡器 2.3.3 传递灰度发布标签 2.4 其他代码 2.4.1 其他业务代码 2.4.2 pom.xml 关键代码 2.4.3 application.yml 相关代码 3. 验证全链路金丝雀发布的实现效果 1. 什么金丝雀发布它有什么用 金丝雀发布(Canary Release,也称为灰度发布)是指在软件或服务发布过程中将新版本的功能或服务以较小的比例引入到生产环境中仅向部分用户或节点提供新功能的一种发布策略。 而在传统的全量发布中新版本将会立即部署到所有用户或节点上。金丝雀发布的核心思想是逐步推进监测新版本的稳定性和性能以确保在全面发布之前能够解决潜在的问题。 假设某款在线多人游戏决定上线一个全新的多人模式功能。在传统的全量发布中它会将这个新功能立即部署到所有玩家的游戏客户端中然后在全面发布后等待用户的反馈。而使用金丝雀发布它的发布流程就变成了这样 内测阶段 游戏开发团队首先将新多人模式功能引入到游戏的内测版本中但仅向少数特定的内测玩家提供。这些内测玩家是经过筛选或自愿参与的他们了解可能会遇到问题并愿意分享反馈。内测玩家可以在一定时间内使用新功能并向开发团队报告问题、提供建议和反馈意见。 监测和改进 游戏开发团队密切关注内测玩家的游戏体验、性能和稳定性。如果在内测期间发现了问题团队可以及时进行修复和改进并确保新功能在全面发布前达到高质量标准。 逐步扩展 在确认新功能在内测阶段表现良好后开发团队逐步扩展金丝雀发布的范围。他们可以将新功能提供给更多的玩家但仍然限制在一小部分比如10%的玩家。这一阶段被称为金丝雀发布的初期阶段新功能仅对一小部分用户可见。 全面发布 在经过一系列逐步扩展和监测后开发团队最终将新多人模式功能发布给了所有玩家。此时新功能已经通过了多轮测试和改进用户体验较好且潜在问题得到了解决。 从上述游戏上线新功能的金丝雀发布流程中能看出金丝雀发布相比传统的全量发布有以下好处 逐步引入新功能降低全面发布的风险。及时获取内测玩家的反馈加速问题的修复。确保新功能在全面发布时达到高质量标准。提供更好的用户体验减少潜在问题对所有用户的影响。 2.如何实现全链路的金丝雀发布 Spring Cloud 全链路金丝雀发布的实现思路图如下 金丝雀发布的具体实现步骤大致分为以下几步 前端程序在灰度测试的用户 Header 头中打上标签例如在 Header 中添加 gray-tagtrue表示要访问灰度服务其他则为正式服务。前端在负载均衡器 Spring Cloud LoadBalancer 中拿到 Header 中的 gray-tag 进行判断如果此标签不为空并且等于 true 的话则表示要访问灰度发布的服务否则只访问正式的服务。客户端负载均衡在网关 Spring Cloud Gateway 中将 Header 标签 gray-tagtrue 传递到下一个调用的服务。网关后续的服务调用中还需要做两件事内部服务 在 Spring Cloud LoadBalancer 中判断灰度发布标签将请求分发给对应的服务。在内部的服务调用过程中传递灰度发布标签。 由此可见全链路的灰色发布只需要解决两个大问题 1. Gateway 中的问题 Gateway 的调度转发问题。Gateway 灰色发布标签的传递问题。 2. 内部服务中的问题 服务的灰度转发问题。服务内部灰色发布标签的传递问题。 【金丝雀发布代码案例】 根据 Spring Cloud 全链路金丝雀发布的实现思路图来编写代码 创建 Spring 多模块项目然后准备 7 个模块user-service、new-user-service、order-service、log-service、new-log-service、gray-loadbalancer、gateway。 2.1 负载均衡模块 操作 gray-loadblancer 模块这个模块作为一个公共模块可以不需要启动类。 ① 自定义负载均衡器 这里可以参考默认的轮询负载均衡策略里面的实现 实现 ReactorServiceInstanceLoadBalancer 接口复制其他代码修改关键地方的类名重写 getInstanceResponse 方法 import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.ObjectProvider; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.*; import org.springframework.cloud.loadbalancer.core.*; import org.springframework.http.HttpHeaders; import reactor.core.publisher.Mono; import java.util.List; import java.util.Random; import java.util.concurrent.atomic.AtomicInteger;/*** 定义灰度发布的负载均衡算法*/public class GrayLoadBalancer implements ReactorServiceInstanceLoadBalancer {private static final Log log LogFactory.getLog(GrayLoadBalancer.class);private final String serviceId;private AtomicInteger position; // 下标private ObjectProviderServiceInstanceListSupplier serviceInstanceListSupplierProvider;public GrayLoadBalancer(ObjectProviderServiceInstanceListSupplier serviceInstanceListSupplierProvider, String serviceId) {this.serviceId serviceId;this.serviceInstanceListSupplierProvider serviceInstanceListSupplierProvider;this.position new AtomicInteger(new Random().nextInt(1000));}public MonoResponseServiceInstance choose(Request request) {ServiceInstanceListSupplier supplier (ServiceInstanceListSupplier)this.serviceInstanceListSupplierProvider.getIfAvailable(NoopServiceInstanceListSupplier::new);return supplier.get(request).next().map((serviceInstances) - {return this.processInstanceResponse(supplier, serviceInstances,request);});}private ResponseServiceInstance processInstanceResponse(ServiceInstanceListSupplier supplier,ListServiceInstance serviceInstances,Request request) {ResponseServiceInstance serviceInstanceResponse this.getInstanceResponse(serviceInstances,request);if (supplier instanceof SelectedInstanceCallback serviceInstanceResponse.hasServer()) {((SelectedInstanceCallback)supplier).selectedServiceInstance((ServiceInstance)serviceInstanceResponse.getServer());}return serviceInstanceResponse;}private ResponseServiceInstance getInstanceResponse(ListServiceInstance instances,Request request) {if (instances.isEmpty()) {if (log.isWarnEnabled()) {log.warn(No servers available for service: this.serviceId);}return new EmptyResponse();} else {// 灰度业务的实现// 0.得到 Request 对象 [通过方法参数的传递拿到此对象]// 1.从 Request 对象的 Header 中得到灰度标签RequestDataContext requestDataContext (RequestDataContext) request.getContext();HttpHeaders headers requestDataContext.getClientRequest().getHeaders();// 获取名为 gray-tag 的头部信息的值ListString headersList headers.get(GlobalVariable.GRAY_TAGE);if (headersList ! null !headersList.isEmpty() headersList.get(0).equals(true)) { // 灰度请求// 灰度列表ListServiceInstance grayList instances.stream().filter(i - i.getMetadata().get(GlobalVariable.GRAY_TAGE) ! null i.getMetadata().get(GlobalVariable.GRAY_TAGE).equals(true)).toList();if(!grayList.isEmpty()) {instances grayList;}} else { // 正式节点// 2.将实例进行进行分组 【生产服务列表|灰度服务列表】instances instances.stream(). // 取反filter(i - i.getMetadata().get(GlobalVariable.GRAY_TAGE) null ||!i.getMetadata().get(GlobalVariable.GRAY_TAGE).equals(true)).toList();}// 3.使用负载均衡算法选择上一步列表中的某个节点int pos this.position.incrementAndGet() Integer.MAX_VALUE;ServiceInstance instance instances.get(pos % instances.size());return new DefaultResponse(instance);}} } /*** 全局变量*/ public class GlobalVariable {public static final String GRAY_TAGE gray-tag; }② 封装负载均衡器 import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer; import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier; import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; import org.springframework.context.annotation.Bean; import org.springframework.core.env.Environment;/*** 封装灰度发布负载均衡器*/ public class GrayLoadBalancerConfig {Beanpublic ReactorLoadBalancerServiceInstance grayLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {String name environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);// 灰度发布的负载均衡器return new GrayLoadBalancer(loadBalancerClientFactory.getLazyProvider(name,ServiceInstanceListSupplier.class), name);} }2.2 网关模块 通过全局过滤器来判断或设置灰度标识 import com.loadbalancer.gray.GlobalVariable; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono;Component public class LoadBalancerFilter implements GlobalFilter {Overridepublic MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 得到 request、response 对象ServerHttpRequest request exchange.getRequest();ServerHttpResponse response exchange.getResponse();// 判断灰度标签String tag request.getQueryParams().getFirst(GlobalVariable.GRAY_TAGE);if(tag ! null) {// 设置灰度标识response.getHeaders().set(GlobalVariable.GRAY_TAGE,true);}// 此步骤正常执行下一步return chain.filter(exchange);} }2.3 服务模块 2.3.1 注册为灰色服务实例 将测试版的服务注册为灰色服务实例new-user-service、new-log-service spring:application:name: user-service-graycloud:nacos:discovery:server-addr: localhost:8848username: nacospassword: nacosmetadata: {gray-tag: true} # 金丝雀标识 server:port: 0 2.3.2 设置负载均衡器 在服务启动类上设置负载均衡和开启 OpenFeign 服务user-service、new-user-service、order-service。 import com.loadbalancer.gray.GrayLoadBalancerConfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients; import org.springframework.cloud.openfeign.EnableFeignClients;SpringBootApplication EnableFeignClients LoadBalancerClients(defaultConfiguration GrayLoadBalancerConfig.class) public class UserServiceApplication {public static void main(String[] args) {SpringApplication.run(UserServiceApplication.class, args);}} 在网关模块中设置负载均衡 import com.loadbalancer.gray.GrayLoadBalancerConfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients;SpringBootApplication LoadBalancerClients(defaultConfiguration GrayLoadBalancerConfig.class) public class GatewayApplication {public static void main(String[] args) {SpringApplication.run(GatewayApplication.class, args);}}2.3.3 传递灰度发布标签 在服务内部传递灰度发布标签user-service、new-user-service、order-service 方式一传递request中所有的header所有的header中就包含了灰度发布标签。 import feign.RequestInterceptor; import feign.RequestTemplate; import jakarta.servlet.http.HttpServletRequest; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes;import java.util.Enumeration;Component public class FeignRequestInterceptor implements RequestInterceptor {Overridepublic void apply(RequestTemplate requestTemplate) {// 从 RequestContextHolder 中获取 HttpServletRequestServletRequestAttributes attributes (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();HttpServletRequest request attributes.getRequest();// 传递所有的 header就包含了灰度发布标签EnumerationString headerNames request.getHeaderNames();while(headerNames.hasMoreElements()) {String key headerNames.nextElement();String value request.getHeader(key);requestTemplate.header(key,value);}} } 方式二只传递header中的灰度发布标签 import feign.RequestInterceptor; import feign.RequestTemplate; import jakarta.servlet.http.HttpServletRequest; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes;import java.util.Enumeration; import java.util.LinkedHashMap; import java.util.Map;Component public class FeignRequestInterceptor implements RequestInterceptor {Overridepublic void apply(RequestTemplate requestTemplate) {// 从 RequestContextHolder 中获取 HttpServletRequestServletRequestAttributes attributes (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();// 获取 RequestContextHolder 中的信息MapString,String headers getHeaders(attributes.getRequest());// 放入 openfeign 的 requestTemplate 中for(Map.EntryString,String entry : headers.entrySet()) {requestTemplate.header(entry.getKey(), entry.getValue());}}/*** 获取原请求头*/private MapString,String getHeaders(HttpServletRequest request) {MapString,String map new LinkedHashMap();EnumerationString enumeration request.getHeaderNames();if(enumeration!null) {while(enumeration.hasMoreElements()) {String key enumeration.nextElement();String value request.getHeader(key);map.put(key,value);}}return map;} }2.4 其他代码 2.4.1 其他业务代码 ① user-service 模块的 controller import com.example.userservice.service.OrderService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;RestController RequestMapping(/user) public class UserController {Autowiredprivate OrderService orderService;RequestMapping(/getname)public String getName() {String result orderService.getOrder();return 正式版User Service getName. result;} }② user-service 模块的 service import org.springframework.cloud.openfeign.FeignClient; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.RequestMapping;FeignClient(order-service-gray) Service public interface OrderService {RequestMapping(/order/getorder)public String getOrder(); }③ new-user-service 模块的 controller import com.example.newuserservice.service.OrderService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;RestController RequestMapping(/user) public class UserController {Autowiredprivate OrderService orderService;RequestMapping(/getname)public String getName() {String result orderService.getOrder();return 测试版User Service getName. result;} }④ new-user-service 模块的 service import org.springframework.cloud.openfeign.FeignClient; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.RequestMapping;FeignClient(order-service-gray) Service public interface OrderService {RequestMapping(/order/getorder)public String getOrder(); }⑤ order-service 模块的 controller import com.example.orderservice.service.LogService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;RestController RequestMapping(/order) public class OrderController {Autowiredprivate LogService logService;RequestMapping(/getorder)public String getOrder() {String result logService.getLog();return Do OrderService getOrder Method. result;} }⑥ order-service 模块的 service import org.springframework.cloud.openfeign.FeignClient; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.RequestMapping;Service FeignClient(log-service-gray) public interface LogService {RequestMapping(/log/getlog)public String getLog(); }⑦ log-service 模块的 controller import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;RestController RequestMapping(/log) public class LogController {RequestMapping(/getlog)public String getLog() {return 正式版Log Service getLog;} } ⑧ new-log-service 模块的 controller import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;RestController RequestMapping(/log) public class LogController {RequestMapping(/getlog)public String getLog() {return 测试版Log Service getLog;} }2.4.2 pom.xml 关键代码 ① 父模块的 pom.xml modules 中先加载服务调用链中靠后的服务 packagingpom/packaging!-- ....省略 --!-- 注意打包顺序 -- modulesmodulegray-loadbalancer/modulemodulegateway/modulemodulenew-log-service/modulemodulelog-service/modulemoduleorder-service/modulemoduleuser-service/modulemodulenew-user-service/module /modules!-- ....省略 --dependencies!-- nacos服务注册 --dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependency!-- 负载均衡 --dependencygroupIdcom.example/groupIdartifactIdgray-loadbalancer/artifactIdversion0.0.1-SNAPSHOT/version/dependency /dependencies ② user-service 模块的 pom.xml parentgroupIdcom.example/groupIdartifactIdgray-demo/artifactIdversion0.0.1-SNAPSHOT/version /parent dependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-openfeign/artifactId/dependency /dependencies ③ new-user-service 模块的 pom.xml parentgroupIdcom.example/groupIdartifactIdgray-demo/artifactIdversion0.0.1-SNAPSHOT/version /parent dependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-openfeign/artifactId/dependencydependencygroupIdcom.example/groupIdartifactIdgray-loadbalancer/artifactIdversion0.0.1-SNAPSHOT/version/dependency /dependencies ③ order-service 模块的 pom.xml parentgroupIdcom.example/groupIdartifactIdgray-demo/artifactIdversion0.0.1-SNAPSHOT/version /parent dependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-openfeign/artifactId/dependencydependencygroupIdcom.example/groupIdartifactIdgray-loadbalancer/artifactIdversion0.0.1-SNAPSHOT/version/dependency /dependencies④ log-service 和 new-log-service 模块的 pom.xml parentgroupIdcom.example/groupIdartifactIdgray-demo/artifactIdversion0.0.1-SNAPSHOT/version /parent dependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency /dependencies ⑤ gray-loadbalancer 模块的 pom.xml parentgroupIdcom.example/groupIdartifactIdgray-demo/artifactIdversion0.0.1-SNAPSHOT/version /parent dependenciesdependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-loadbalancer/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency /dependencies ⑥ gateway 模块的 pom.xml parentgroupIdcom.example/groupIdartifactIdgray-demo/artifactIdversion0.0.1-SNAPSHOT/version /parent dependenciesdependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-gateway/artifactId/dependencydependencygroupIdcom.example/groupIdartifactIdgray-loadbalancer/artifactIdversion0.0.1-SNAPSHOT/version/dependency /dependencies 2.4.3 application.yml 相关代码 ① user-service 模块的 application.yml spring:application:name: user-service-graycloud:nacos:discovery:server-addr: localhost:8848username: nacospassword: nacos server:port: 0② new-user-servicce 模块的 application.yml spring:application:name: user-service-graycloud:nacos:discovery:server-addr: localhost:8848username: nacospassword: nacosmetadata: {gray-tag: true} # 金丝雀标识 server:port: 0 ③ order-servicce 模块的 application.yml spring:application:name: order-service-graycloud:nacos:discovery:server-addr: localhost:8848username: nacospassword: nacos server:port: 0④ log-servicce 模块的 application.yml spring:application:name: log-service-graycloud:nacos:discovery:server-addr: localhost:8848username: nacospassword: nacos server:port: 0 ⑤ new-log-servicce 模块的 application.yml spring:application:name: log-service-graycloud:nacos:discovery:server-addr: localhost:8848username: nacospassword: nacosmetadata: {gray-tag: true} # 金丝雀标识 server:port: 0⑥ gateway 模块的 application.yml spring:main:web-application-type: reactive # Spring Web 和 reactive web 冲突application:name: gateway-graycloud:nacos:discovery:server-addr: localhost:8848username: nacospassword: nacosregister-enabled: false # 网关不需要注册到 nacosgateway:routes:- id: user-serviceuri: lb://user-service-graypredicates:- Path/user/** server:port: 10086 3. 验证全链路金丝雀发布的实现效果 按顺序启动 log、order、user 的正式及测试服务以及 gateway 模块 使用 Postman 来验证全链路金丝雀发布的实现效果 1. 请求头中不带 gray-tag 灰度标签访问正式版服务 验证结果无论访问多少次不管是否服务集群只要请求头中不带 gray-tag 灰度标签只能访问到正式版的服务。 2. 请求头中带上 gray-tag 灰度标签并且值为 true访问测试版服务 验证结果无论访问多少次不管是否服务集群只要请求头中带上 gray-tag 灰度标签并且值为 true 就只能访问到测试版的服务。 至此微服务中全链路的金丝雀发布就实现好了~
http://www.pierceye.com/news/173549/

相关文章:

  • 网站题头是什么做线上网站需要钱吗
  • 陕西省建设工程监理协会网站 查询动易网站首页错位
  • 老公做网站网站推广wordpress 文件加载顺序
  • 网站开发保存学习进度的方案搭建网站免费
  • 做网站对外贸有什么用网站怎么防k
  • 网站开发网站建设常州建站程序
  • 赤峰建设局网站物流公司网站制作模板
  • 装修第三方平台网站建设网站开发及设计
  • 男女做那个的小视频网站个人如何注册公司流程
  • 机关网站建设前期准备工作wordpress替代
  • 机关网站建设无锡宜兴网站建设
  • 江苏景禾瑜博建设工程有限公司网站做网站注册公司
  • 如何找到做网站的客户贵州二建报名入口官网
  • 网站怎么做301定向wordpress极客式主题
  • 造价工程建设协会网站怎么把做的网站发布
  • 万网网站首页好企业网站
  • 廊坊做网站电话企业网络搭建拓扑图
  • 建设社区网站有什么借鉴之处专业网站制作哪家专业
  • 南宁网站推广流程wordpress 雅黑字体
  • 个人网站制作代码河北seo基础知识
  • 国内做视频的网站有哪些企业网站价格花
  • 泰安网站推广优化wordpress首页图片
  • 政协网站建设更改wordpress管理员用户名
  • 网站浏览器兼容性通用有那种网站么
  • 网站中全景是怎么做的云南网络营销文化优化
  • 苏州网站优化哪家好换空间对网站的影响
  • 如何做黑客攻击网站专业的网站建设运营
  • 门户网站建站流程做网站在哪里做比较好
  • 青创网站首页wordpress用户发文章
  • wordpress 仿站 主题网站建设拍金手指排名贰拾