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

网站排名掉了网站开发流程图

网站排名掉了,网站开发流程图,网站制作毕业设计论文,网站流量超限从 Zuul 迁移到 Spring Cloud Gateway#xff1a;一步步实现服务网关的升级 迁移前的准备工作迁移步骤详解第一步#xff1a;查看源码第二步#xff1a;启动类迁移第三步#xff1a;引入 Gateway 依赖第四步 编写bootstrap.yaml第五步#xff1a;替换路由配置第六步#… 从 Zuul 迁移到 Spring Cloud Gateway一步步实现服务网关的升级 迁移前的准备工作迁移步骤详解第一步查看源码第二步启动类迁移第三步引入 Gateway 依赖第四步 编写bootstrap.yaml第五步替换路由配置第六步迁移过滤器逻辑第七步测试与调优 迁移过程中常见问题及解决方案真实问题**注意事项Nginx 转发配置的调整****问题背景****解决方法** 总结 公司的项目之前使用的是Zuul然后使用的是以前传下来的jar包JDK1.8,spring1.*都是比较老了然后因为这些原因要把Zuul替换成Gateway。 本文将详细介绍如何从 Zuul 迁移到 Gateway。 迁移前的准备工作 在开始迁移之前需要做好以下准备 确认现有的 Zuul 配置 收集 Zuul 的路由配置、过滤器逻辑和插件依赖。 学习 Gateway 的基本概念 熟悉 Gateway 的核心概念例如 Route路由Predicate断言Filter过滤器 确保系统支持响应式编程模型 检查项目中的依赖库和代码是否与 Spring WebFlux 的非阻塞模型兼容。 升级到支持 Gateway 的 Spring Boot 版本 确保 Spring Boot 版本 2.1。 迁移步骤详解 第一步查看源码 由于项目使用的是预先打包好的 Jar 文件源码不可直接查看因此需要通过反编译工具提取代码。我使用的是 jd-gui 工具界面如图所示 从反编译的结果可以看到代码量相对简单主要包含两个部分启动类和核心过滤器。相对比较容易。 第二步启动类迁移 原 Zuul 启动类 EnableZuulProxy SpringBootApplication public class ZuulServerApplication {public static void main(String[] args) {(new SpringApplicationBuilder(ZuulServerApplication.class)).web(true).run(args);}Beanpublic PathRewriteHeaderFilter customAddHeaderFilter(RouteLocator routeLocator) {return new PathRewriteHeaderFilter(routeLocator);} }迁移后的 Gateway 启动类 SpringBootApplication EnableDiscoveryClient ComponentScan(basePackages {com.aspire.gateway.gatewayservice}) public class GatewayServiceApplication {public static void main(String[] args) {SpringApplication.run(GatewayServiceApplication.class, args);} }Spring Boot 2.x 后EnableZuulProxy 不再需要Gateway 默认支持路由功能。由于项目的特殊需求需要添加 ComponentScan 手动指定 Bean 扫描路径确保组件能够被正确加载。因为spring2之后的版本不需要再显示指定Gateway了其实理论上只需要一个SpringBootApplication就够了其他其实都不用。但是我这里不知道为啥扫描不到我的bean所以我就写了扫描当前启动类。ComponentScan(basePackages {com.aspire.gateway.gatewayservice})这里你可以换成自己的扫描包路径。 第三步引入 Gateway 依赖 在 pom.xml 中移除 Zuul 相关依赖替换为 Gateway 依赖 以下是我使用的版本控制就是这些版本之间是兼容的我使用的也是这些版本。 propertiesjava.version17/java.versionproject.build.sourceEncodingUTF-8/project.build.sourceEncodingproject.reporting.outputEncodingUTF-8/project.reporting.outputEncodingspring-cloud.version2024.0.0/spring-cloud.version !-- Spring Cloud 2024.x --spring-cloud-alibaba.version2022.0.0.0-RC2/spring-cloud-alibaba.version !-- Spring Cloud Alibaba 对应版本 --keycloak.version22.0.4/keycloak.version !-- 非必须我的项目需要你不用就删掉 --/properties dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-gateway/artifactId /dependency这一步主要就是导入你的依赖嘛。 第四步 编写bootstrap.yaml 这一块里面其实主要就是你的nacos的配置文件反正我用的是nacos因为Zuul是网关嘛Gateway也是网关然后你实际的服务和网关都是要在同一个服务发现下面的我之前是eureka现在是nacos所以要在这里说明的。 spring:main:allow-circular-references: trueallow-bean-definition-overriding: trueapplication:name: rbac-gatewaycloud:nacos:username: ${ENV_CONFIG_USERNAME:nacos}password: ${ENV_CONFIG_PASSWORD:}server-addr: ${ENV_CONFIG_IP:10.*.*.*}:${ENV_CONFIG_PORT:*}# Nacos 服务发现配置discovery:enabled: true # 启用服务发现service: ${spring.application.name} # 使用应用名作为服务名server-addr: ${ENV_CONFIG_IP:*}:${ENV_CONFIG_PORT:*}namespace: ${NAMESPACE:*}#group: ${spring.cloud.nacos.discovery.group:*}group: *metadata:version: v1env: prod# Nacos 配置中心配置config:enabled: trueserver-addr: ${ENV_CONFIG_IP:*}:${ENV_CONFIG_PORT:*} # group: ${spring.cloud.nacos.discovery.group:*}group: *namespace: ${NAMESPACE:*}file-extension: ymlshared-configs:- data-id: ${CONFIG_DATA_ID:ms-gateway.yml}group: *refresh: truetimeout: 600000config-long-poll-timeout: 5000config-retry-time: 2000max-retry: 3refresh-enabled: true 第五步替换路由配置 将 Zuul 的 application.yml 配置迁移为 Gateway 的路由配置。这一块实际上就比较复杂了因为他们之间的切换还是很麻烦的所以我这里是直接使用AI帮我替换的你也可以这样。 反正差不多样子就是如下吧。直接让AI帮你替换然后你看一眼就行了。我反正是这么搞的然后也没啥问题。 Zuul 配置 zuul:#semaphore:max-semaphores: 1000servlet-path: /host:connect-timeout-millis: 60000socket-timeout-millis: 60000#routes:smartdata-check:path: /smartCheckservice-id: rbacstrip-prefix: falsesmartdata-token-init:path: /v1/smartdata/tokenservice-id: rbacstrip-prefix: falsecomposite-roles:path: /v1/roles/**service-id: rbacstrip-prefix: falseGateway 配置 spring:cloud:gateway:routes:- id: ssouri: lb://rbacpredicates:- Path/v1/alerts/sso/**- id: smartdata-checkuri: lb://rbacpredicates:- Path/smartCheck- id: smartdata-token-inituri: lb://rbacpredicates:- Path/v1/smartdata/token- id: composite-rolesuri: lb://rbacpredicates:- Path/v1/roles/**其实没有全局过滤器已经可以用了就是网关服务已经是可以用了。到这里其实就已经结束了。服务能用。不看后面也行我为什么要替换呢因为我想完美迁移。 第六步迁移过滤器逻辑 Zuul 使用过滤器机制来处理请求而 Gateway 则使用过滤器工厂。这一块就比较复杂了也是我花的最多时间的一步了。 原本的Zuul 过滤器 import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.keycloak.KeycloakSecurityContext; import org.keycloak.representations.AccessToken; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cloud.netflix.zuul.filters.Route; import org.springframework.cloud.netflix.zuul.filters.RouteLocator; import org.springframework.web.util.UrlPathHelper;public class PathRewriteHeaderFilter extends ZuulFilter {private static final Logger log LoggerFactory.getLogger(com.migu.tsg.microservice.zuul.PathRewriteHeaderFilter.class);private RouteLocator routeLocator;private final UrlPathHelper urlPathHelper new UrlPathHelper();private static final String EMPLOYEE_TYPE employeeType;private static final String ORG_ACCOUNT head_orgAccount;private static final String IS_ADMIN head_isAdmin;private static final String IS_SUPERUSER head_isSuperUser;private static final String USER_NAME head_userName;private static final String FALSE false;private static final String TRUE true;private static final String ADMIN admin;private static final String ROOT root;private static final Integer SIX Integer.valueOf(6);private static final String COLON :;public PathRewriteHeaderFilter() {}public PathRewriteHeaderFilter(RouteLocator routeLocator) {this.routeLocator routeLocator;}public int filterOrder() {return SIX.intValue();}public String filterType() {return pre;}public boolean shouldFilter() {return true;}public Object run() {RequestContext requestContext RequestContext.getCurrentContext();String requestURI this.urlPathHelper.getPathWithinApplication(requestContext.getRequest());Route route this.routeLocator.getMatchingRoute(requestURI);try {if (route ! null) {String location route.getLocation();log.info(location: {}, location);if (location ! null) {HttpServletRequest request requestContext.getRequest();KeycloakSecurityContext securityContext (KeycloakSecurityContext)request.getAttribute(KeycloakSecurityContext.class.getName());handleRewriteHeader(securityContext, requestContext);if (location.startsWith(http:) || location.startsWith(https:))log.info(forward url is : location); } } } catch (Exception e) {requestContext.set(error.status_code, Integer.valueOf(500));requestContext.set(error.message, e.getCause());requestContext.set(error.exception, e);} return null;}private void handleRewriteHeader(KeycloakSecurityContext securityContext, RequestContext requestContext) {log.info(keycloak securityContext {}, securityContext);if (securityContext null)return; AccessToken token securityContext.getToken();MapString, Object otherClaims token.getOtherClaims();log.info(keycloak token {}, otherClaims {}, token, otherClaims);String employeeType (String)otherClaims.get(employeeType);String userName (String)otherClaims.get(userName);String orgAccount ;String isSupperUser false;String isAdmin false;if (employeeType.equals(root)) {isSupperUser true;orgAccount userName;} if (employeeType.equals(admin)) {isAdmin true;orgAccount userName;} if (!employeeType.equals(root) !employeeType.equals(admin)) {int index employeeType.indexOf(.) 1;orgAccount employeeType.substring(index, employeeType.length());} log.info(employeeType: {}, head_userName: {}, head_isSuperUser: {}, head_orgAccount: {}, head_isAdmin: {}, new Object[] { employeeType, userName, isSupperUser, orgAccount, isAdmin });requestContext.addZuulRequestHeader(head_userName, userName);requestContext.addZuulRequestHeader(head_isSuperUser, isSupperUser);requestContext.addZuulRequestHeader(head_orgAccount, orgAccount);requestContext.addZuulRequestHeader(head_isAdmin, isAdmin);} } 但是我是想完美的等量替换所以这里就把原本的过滤器也给拿过来了。可以看到是少了一些东西了因为原本的方法有很多东西是用不到的我就把那些东西给删掉了。只保留了用到的东西 反正我测下来是没啥问题反正就是实现起来差别真的很大首先是extends ZuulFilter不用了改成了GlobalFilter 然后里面的实现也从public Object run() 变成了public MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) 然后具体的实现逻辑也变了这一块呢就是自己琢磨着改吧。每一个过滤器都不一样反正大体逻辑就是实现的方法不一样了然后重写的方法不一样了。这两个是最主要的。 实现的接口不一样重写的方法不一样 其实主要把握这两个就行里面就是具体的代码逻辑了。 替换后的Gateway 全局过滤器 Component Order(6) // 这里使用 Order 注解来设置过滤器顺序 public class PathRewriteHeaderFilter implements GlobalFilter {private static final Logger log LoggerFactory.getLogger(PathRewriteHeaderFilter.class);Overridepublic MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) {try {String requestURI exchange.getRequest().getURI().getPath();log.info(Request URI: {}, requestURI);// 在此处你可以获取并处理 Keycloak 的 securityContext 和 tokenKeycloakSecurityContext securityContext exchange.getAttribute(KeycloakSecurityContext.class.getName());if (securityContext ! null) {AccessToken token securityContext.getToken();MapString, Object otherClaims token.getOtherClaims();log.info(keycloak token {}, otherClaims {}, token, otherClaims);String employeeType (String) otherClaims.get(employeeType);String userName (String) otherClaims.get(userName);String orgAccount ;String isSuperUser false;String isAdmin false;if (root.equals(employeeType)) {isSuperUser true;orgAccount userName;} else if (admin.equals(employeeType)) {isAdmin true;orgAccount userName;} else {int index employeeType.indexOf(.) 1;orgAccount employeeType.substring(index);}log.info(employeeType: {}, head_userName: {}, head_isSuperUser: {}, head_orgAccount: {}, head_isAdmin: {},employeeType, userName, isSuperUser, orgAccount, isAdmin);exchange.getRequest().mutate().header(head_userName, userName).header(head_isSuperUser, isSuperUser).header(head_orgAccount, orgAccount).header(head_isAdmin, isAdmin).build();}} catch (Exception e) {log.error(Error processing request, e);}return chain.filter(exchange);} }第七步测试与调优 功能测试 验证迁移后的路由和过滤器逻辑是否正常工作。 我这里是正常的没有问题的。 性能测试 测试 Gateway 的吞吐量和延迟确保性能满足要求。 监控与日志 配置 Gateway 的监控和日志及时捕获异常和瓶颈。 迁移过程中常见问题及解决方案 问题某些依赖库与 WebFlux 不兼容 解决方案 更新相关依赖或寻找替代方案确保与 WebFlux 模型兼容。 问题路由配置规则变更导致服务无法访问 解决方案 仔细对比 Zuul 和 Gateway 的配置方式确保路径匹配规则正确。 问题过滤器执行顺序混乱 解决方案 合理设置过滤器的 Order 值并明确其执行逻辑。 真实问题 注意事项Nginx 转发配置的调整 在迁移过程中有一个细节需要特别注意那就是 Nginx 的转发规则。以下是我遇到的问题和解决方法希望能对你有所帮助。 问题背景 在原有的 Zuul 部署环境中我使用的是 IP端口 的形式进行服务转发。由于迁移初期 IP 和端口并未发生改变所以 Nginx 的配置无需修改服务能够正常使用。然而当将 Gateway 部署到云原生环境如 Kubernetes后问题随之出现。 云原生环境中服务之间的通信通常使用 服务名:端口 的形式而不是 IP 地址。因此原本在 Nginx 中配置的 qams-zuul-server 服务名需要进行修改否则转发规则无法正确匹配导致请求失败。 解决方法 检查原有的 Nginx 配置 原有配置通常类似以下形式 location ^~/v1/ {proxy_pass http://zuulServer;}location ^~/v2/ {#proxy_pass http://10.24.88.160:5566;proxy_pass http://10.12.7.115:5566;}location ^~/zuul/ {#proxy_pass http://10.24.88.160:5566;proxy_pass http://10.12.7.115:5566;}location ^~/download/ {proxy_pass http://10.24.88.160:2222;} 这种配置基于固定的 IP 和端口在云原生环境下无法适用。 修改为基于服务名的配置 在云原生环境中需要将 10.12.7.115 的地址替换为服务名示例如下 location ^~/v1/ { proxy_pass http://qams-gateway-server:5566;}location ^~/v2/ { proxy_pass http://qams-gateway-server:5566; } location ^~/gateway/ { proxy_pass http://qams-gateway-server:5566; }location ^~/download/ { proxy_pass http://qams-gateway-server:2222; }注意 服务名 qams-gateway-service 必须与云原生环境中定义的服务名称一致。确保 Nginx 能够解析服务名。通常情况下Nginx 部署在同一 Kubernetes 集群内DNS 解析应当是自动支持的。 重启 Nginx 并测试 完成修改后重启 Nginx 并通过实际访问测试转发是否正常。 迁移的时候注意nginx的转发我之前呢是因为我使用的是IP端口的形式然后我的IP和端口实际上并没有发生改变所以我的Nginx没改然后服务依旧能正常使用。 但是当我把Gateway迁移到云原生环境下的时候就不太行了因为云原生环境使用的是服务名端口的格式所以他原本的服务名称为qams-zuul-server要换成下面的格式就是nginx也要需要这个不要忘记了。 总结 从 Zuul 迁移到 Spring Cloud Gateway 是一次提升系统性能和功能的好机会。通过合理规划和逐步迁移可以平稳完成网关的升级并充分利用 Gateway 的新特性来优化系统架构。 希望这篇文章能为你的迁移过程提供有价值的参考如果你在迁移过程中遇到问题欢迎留言讨论。
http://www.hkea.cn/news/14287690/

相关文章:

  • 苍南做网站深圳市在建项目查询
  • 重庆微信网站开发做网站和做新媒体运营
  • 网站备案登记昆明响应式网站
  • 网站打不开了什么原因网站页面建设
  • 桂林旅游网站建设佛山营销网站建设多少钱
  • 毕业设计做网站老师会问什么做网站必须原创吗
  • 专门做运动装备的网站一加网站开发
  • 东莞高端网站建设多少钱怎样用自己的电脑做网站
  • 企业营销系统和网站建设网站建设主要推广方式
  • 国外个人网站给公司做个网站多少钱
  • 门户网站系统建设招标文件wordpress官网密码错误
  • 网站怎么重建今天刚刚长沙又增加了一例
  • 电子商务网站建设问题企业彩铃制作网站
  • 专做轮胎的网站网站建设数据表设计 性别
  • 营销网站模板wordpress qq邮箱留言
  • 买奢侈品代工厂做的产品的网站名怎么申请免费企业邮箱账号
  • 网站响应式技术wordpress 主页不显示图片
  • 怎么查网站是谁建的盐山县网站建设
  • 怎么黑进网站后台工程建设分为哪几个阶段
  • 个人如何制作网站长沙投资公司排名
  • 企业网站开发模板下载百度搜索不到网站
  • 成都展示型网站开发怎么样创建微信公众号
  • 网站建设方案书写专门制作网站
  • 哈尔滨网站建设方案策划石景山老山网站建设
  • 搭建网站的流程温州网站建设和推广
  • 学习软件有哪些宁波网站搜索优化
  • 浙江品牌网站设计专家php网站 缓存
  • wordpress建站比较建设网站的价值
  • 合肥做网站行吗码支付wordpress用不
  • 网站建设是什么部门wordpress 首页设置幻灯片