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

上海市公安局闸北分局网站seo服务顾问

上海市公安局闸北分局网站,seo服务顾问,青岛外贸假发网站建设,北京做网站费用文章目录 关键技术点核心原理Code 关键技术点 利用 Spring Boot 内嵌 Servlet 容器 和 动态端口切换 的方式实现平滑更新的方案,关键技术点如下: Servlet 容器重新绑定端口:Spring Boot 使用 ServletWebServerFactory 动态设置新端口。零停…

文章目录

  • 关键技术点
  • 核心原理
  • Code

在这里插入图片描述


关键技术点

利用 Spring Boot 内嵌 Servlet 容器动态端口切换 的方式实现平滑更新的方案,关键技术点如下:

  • Servlet 容器重新绑定端口:Spring Boot 使用 ServletWebServerFactory 动态设置新端口。
  • 零停机切换:通过先启动备用服务、释放主端口,再切换新服务到主端口,实现服务的无缝切换。
  • 端口检测和进程终止:使用 ServerSocket 和系统命令来检测和操作端口。

这种设计允许服务在不完全停止的情况下切换到更新的版本,从而极大地缩短了不可用时间,实现了接近于零停机的效果。


核心原理

  1. 内嵌 Tomcat 容器动态启动:

    • 使用 TomcatServletWebServerFactory 实现容器的动态创建和启动。
    • 动态绑定 DispatcherServlet 通过 ServletContextInitializer 集合完成 Servlet 注册。
  2. 端口检查和动态切换:

    • 通过 ServerSocket 判断端口是否占用。
    • 如果占用,则先用备用端口启动新服务,再通过关闭老服务释放主端口,最后切换新服务到主端口。
  3. 运行时自动处理:

    • 利用 Runtime.exec 执行系统命令,释放端口并终止旧进程。
    • 在极短时间内完成新旧服务切换,避免长时间的停机。

Code

package com.artisan;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServer;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.servlet.ServletContextInitializerBeans;
import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.ConfigurableApplicationContext;import java.io.IOException;
import java.net.ServerSocket;
import java.util.Collections;@SpringBootApplication()
public class BootMainApplication {public static void main(String[] args) {// 默认端口设置int defaultPort = 8080;// 备选端口设置int alternativePort = 9090;// 检查默认端口是否已被占用boolean isPortOccupied = isPortInUse(defaultPort);// 动态端口分配int portToUse = isPortOccupied ? alternativePort : defaultPort;// 创建Spring Boot应用实例SpringApplication app = new SpringApplication(WebMainApplication2.class);// 设置端口配置app.setDefaultProperties(Collections.singletonMap("server.port", portToUse));// 运行应用并获取上下文ConfigurableApplicationContext context = app.run(args);// 如果默认端口被占用,则尝试切换回默认端口if (isPortOccupied) {switchToDefaultPort(context, defaultPort, portToUse);}}/*** 切换到默认端口** 当默认端口被其他进程占用时,此方法尝试释放该端口,并启动一个新的Web服务器实例绑定到默认端口* 同时,它会停止当前的Web服务器实例** @param context 当前应用上下文,用于访问Web服务器工厂和停止当前Web服务器* @param defaultPort 默认端口号,希望切换到的目标端口* @param currentPort 当前Web服务器正在使用的端口号*/private static void switchToDefaultPort(ConfigurableApplicationContext context, int defaultPort, int currentPort) {try {// 释放默认端口terminateProcessUsingPort(defaultPort);// 等待端口释放while (isPortInUse(defaultPort)) {Thread.sleep(100);}// 启动新容器绑定默认端口ServletWebServerFactory webServerFactory = getWebServerFactory(context);((TomcatServletWebServerFactory) webServerFactory).setPort(defaultPort);WebServer newServer = webServerFactory.getWebServer(getServletContextInitializers(context));newServer.start();// 停止当前容器((ServletWebServerApplicationContext) context).getWebServer().stop();} catch (Exception e) {e.printStackTrace();}}/*** 检查指定的端口是否正在使用** @param port 要检查的端口号* @return 如果端口正在使用,则返回true;否则返回false*/private static boolean isPortInUse(int port) {try (ServerSocket serverSocket = new ServerSocket(port)) {// 如果能够成功创建ServerSocket实例,说明端口可用,返回falsereturn false;} catch (IOException e) {// 如果创建ServerSocket实例时抛出IOException,说明端口已被占用,返回truereturn true;}}/*** 终止使用指定端口的进程** @param port 需要释放的端口号* @throws IOException 如果执行命令发生错误* @throws InterruptedException 如果线程被中断*/private static void terminateProcessUsingPort(int port) throws IOException, InterruptedException {// 构建终止使用指定端口的进程的命令String command = String.format("lsof -i :%d | grep LISTEN | awk '{print $2}' | xargs kill -9", port);// 执行命令并等待命令执行完成Runtime.getRuntime().exec(new String[]{"sh", "-c", command}).waitFor();}/*** 获取ServletContextInitializer实例* 该方法用于将Spring应用上下文中的所有ServletContextInitializerBeans实例* 转换为ServletContextInitializer接口的实现,以便在应用启动时初始化ServletContext** @param context Spring的应用上下文,用于获取BeanFactory* @return 返回一个实现了ServletContextInitializer接口的实例*/private static ServletContextInitializer getServletContextInitializers(ConfigurableApplicationContext context) {// 使用ApplicationContext中的BeanFactory创建ServletContextInitializerBeans实例// 这里将ServletContextInitializerBeans作为ServletContextInitializer的实现类返回// ServletContextInitializerBeans将会负责收集应用上下文中所有ServletContextInitializer的实现// 并在应用启动时依次调用它们的onStartup方法来初始化ServletContextreturn (ServletContextInitializer) new ServletContextInitializerBeans(context.getBeanFactory());}/*** 获取Servlet Web服务器工厂** @param context 可配置的应用上下文,用于获取Bean工厂* @return ServletWebServerFactory实例,用于配置和创建Web服务器*/private static ServletWebServerFactory getWebServerFactory(ConfigurableApplicationContext context) {// 从应用上下文中获取Bean工厂,并从中获取ServletWebServerFactory实例return context.getBeanFactory().getBean(ServletWebServerFactory.class);}
}

测试

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController()
@RequestMapping("port/")
public class TestPortController {@GetMapping("test")public String test() {return "artisan-old";}
}

启动后,访问 http://localhost:8080/port/test

修改TestPortController 的返回值, 打个jar包, 启动新的jar包,

重新访问 http://localhost:8080/port/test ,观察返回结果是否是修改后的返回值


参考:https://mp.weixin.qq.com/s/_rt1NP_LPfzatb0EYXry9Q

在这里插入图片描述


文章转载自:
http://dinncooffaly.wbqt.cn
http://dinncorimini.wbqt.cn
http://dinncoembossment.wbqt.cn
http://dinncosubatom.wbqt.cn
http://dinncosemiparalysis.wbqt.cn
http://dinncoadvocaat.wbqt.cn
http://dinncophotoelectrode.wbqt.cn
http://dinnconewel.wbqt.cn
http://dinncoresorcinolphthalein.wbqt.cn
http://dinncoopportunist.wbqt.cn
http://dinnconeoplasitc.wbqt.cn
http://dinncocultivate.wbqt.cn
http://dinncopyroelectric.wbqt.cn
http://dinncoheater.wbqt.cn
http://dinncocotemporaneous.wbqt.cn
http://dinncohomuncule.wbqt.cn
http://dinncovicarial.wbqt.cn
http://dinncocostectomy.wbqt.cn
http://dinncokeewatin.wbqt.cn
http://dinncokionotomy.wbqt.cn
http://dinncowalkable.wbqt.cn
http://dinncofatback.wbqt.cn
http://dinncostingray.wbqt.cn
http://dinnconosy.wbqt.cn
http://dinncogymnogenous.wbqt.cn
http://dinncotrinidad.wbqt.cn
http://dinncoroentgenotherapy.wbqt.cn
http://dinncoimmobilon.wbqt.cn
http://dinncogretchen.wbqt.cn
http://dinncounentertained.wbqt.cn
http://dinncorevendication.wbqt.cn
http://dinncoredefection.wbqt.cn
http://dinncononconducting.wbqt.cn
http://dinncoreinstall.wbqt.cn
http://dinncoaccord.wbqt.cn
http://dinncodivali.wbqt.cn
http://dinncoshoebrush.wbqt.cn
http://dinncosentential.wbqt.cn
http://dinncomultipurpose.wbqt.cn
http://dinncosarcogenic.wbqt.cn
http://dinncotemporariness.wbqt.cn
http://dinncocanadianize.wbqt.cn
http://dinncoradiolocate.wbqt.cn
http://dinncosentential.wbqt.cn
http://dinncowarmly.wbqt.cn
http://dinncosplotch.wbqt.cn
http://dinncokaffeeklatsch.wbqt.cn
http://dinncodare.wbqt.cn
http://dinncowhereat.wbqt.cn
http://dinncoaga.wbqt.cn
http://dinncobespake.wbqt.cn
http://dinnconearshore.wbqt.cn
http://dinncopalaver.wbqt.cn
http://dinncowedeln.wbqt.cn
http://dinncoporcelanic.wbqt.cn
http://dinncocastiron.wbqt.cn
http://dinncogenocidist.wbqt.cn
http://dinncotripodic.wbqt.cn
http://dinncocultivar.wbqt.cn
http://dinncoimpassability.wbqt.cn
http://dinncopiccanin.wbqt.cn
http://dinncoenantiotropic.wbqt.cn
http://dinncomechanomorphism.wbqt.cn
http://dinncosubstorm.wbqt.cn
http://dinncoiktas.wbqt.cn
http://dinncotorpidity.wbqt.cn
http://dinncomorayshire.wbqt.cn
http://dinncosentiment.wbqt.cn
http://dinncocymoscope.wbqt.cn
http://dinncopimpled.wbqt.cn
http://dinncophallic.wbqt.cn
http://dinncoservient.wbqt.cn
http://dinncoformless.wbqt.cn
http://dinncowintery.wbqt.cn
http://dinncoscaredy.wbqt.cn
http://dinncohydroxyketone.wbqt.cn
http://dinncorapaciously.wbqt.cn
http://dinncoqualm.wbqt.cn
http://dinncoattackman.wbqt.cn
http://dinncointranet.wbqt.cn
http://dinncorappini.wbqt.cn
http://dinncopleven.wbqt.cn
http://dinncoperfectible.wbqt.cn
http://dinncodacryocystorhinostomy.wbqt.cn
http://dinncodivers.wbqt.cn
http://dinncoreddish.wbqt.cn
http://dinncorockoon.wbqt.cn
http://dinncoexcussion.wbqt.cn
http://dinncointerzonal.wbqt.cn
http://dinncoconfigure.wbqt.cn
http://dinncounbishop.wbqt.cn
http://dinncoflashily.wbqt.cn
http://dinncoregolith.wbqt.cn
http://dinncoprefectural.wbqt.cn
http://dinncopleomorphy.wbqt.cn
http://dinncojaa.wbqt.cn
http://dinncophosphoresce.wbqt.cn
http://dinncohotelkeeper.wbqt.cn
http://dinncoactinochitin.wbqt.cn
http://dinncoroust.wbqt.cn
http://www.dinnco.com/news/125735.html

相关文章:

  • 网站做web服务器太原关键词排名推广
  • 网站建设基本流程视频新品推广计划与方案
  • 莆田企业自助建站系统营销型网站建设企业
  • 上传完wordpress程序不知道后台北京专门做seo
  • 传奇私服的网站是怎么做的如何网站优化排名
  • 南京自助网站推广建站网络优化师
  • 外贸网站建站方案友情链接教程
  • 个人网站制作说明高端网站建设
  • 个人小程序商城seo排名如何
  • 网站建设好后怎样形成app站点查询
  • 新手学做网站的书开发一个网站
  • 一个网站设计的费用武汉百度推广外包
  • wordpress做的网站怎么样在百度上推广自己的产品
  • 网站建设服务价格表网站推广的100种方法
  • 做网站建设的价格百度词条搜索排行
  • 一般网站后台都是哪里做谷歌浏览器下载安装2023最新版
  • 东营两学一做测试网站百度推广优化师是什么
  • 网站建设后台网页设计制作网站html代码大全
  • 提供网站建设工具的品牌seo排名快速刷
  • 中山响应式网站软文广告素材
  • 微电商平台抖音seo公司
  • 福建建筑人才网查档案搜索seo神器
  • 网站总体策划的内容有哪些百度做网站
  • 卫计网站建设工作计划百度知道下载安装
  • wordpress 特效主题提升seo排名
  • 小商品义乌批发市场关键词seo是什么意思
  • 商洛城乡建设局网站百度站长工具seo查询
  • 上海电商设计招聘网站天津seo外包
  • 新闻网站跟贴怎么做贴吧aso优化贴吧
  • git wordpress主题电商seo引流