日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

3306端口_Spring Boot随机端口你都不会,怎么动态扩容?

發布時間:2025/3/20 javascript 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 3306端口_Spring Boot随机端口你都不会,怎么动态扩容? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一般情況下每個spring boot工程啟動都有固定的端口,但是固定端口不利用服務的動態擴容,如果在一臺服務器上需要對同一個服務進行多實例部署,很容易出現端口沖突,那么怎么解決這個問題呢?

random隨機端口

在spring boot中,可以通過${random}來生成隨機數字,我們可以在配置文件中,這么設置端口:

server.port=${random.int(2000,8000)}

通過http://random.int方法,指定生成2000~8000的隨機端口。這樣每次啟動的端口都不一樣。

多次啟動,發現每次的端口都不一致說明配置成功。

注意事項:

這里需要注意spring boot項目啟動屬性文件的加載順序,spring boot的屬性是由里向外加載,所以最外層的最后被加載,會覆蓋里層的屬性。

所以如果主動在啟動命令中使用–server.port配置了項目的端口號,那么屬性文件中配置的隨機端口屬性就不會生效。

通過System.setProperty設置有效隨機端口

上面的方法雖然暫時達到了想要的效果,但是有個問題:如果生成的這個隨機端口已經被使用了,那么項目啟動就會出現端口沖突。

那么,我們能否通過一個檢測機制,讓生成的隨機端口一定是一個沒有被占用的有效的隨機端口呢?

有效端口檢測原理:

通過建立socket連接,Socket socket = new Socket(Address,port);#address代表主機的IP地址,port代表端口號

如果對該主機的特定端口號能建立一個socket,則說明該主機的該端口在使用。

Socket socket = new Socket(Address,port);#address代表主機的IP地址,port代表端口號

如果對該主機的特定端口號能建立一個socket,則說明該主機的該端口在使用。

實現思路:

通過在項目啟動前,獲取有效的隨機端口并通過System.setProperty將變量設置到系統的全局變量中,這樣項目啟動時就可以從全局變量中獲取到server.port變量的值。

這里的system,系統指的是 JRE (runtime)system,即設置jvm運行時的全局變量。

工具類:

@Slf4j public class NetUtils {/*** 測試本機端口是否被使用* @param port* @return*/public static boolean isLocalPortUsing(int port){boolean flag = true;try {//如果該端口還在使用則返回true,否則返回false,127.0.0.1代表本機flag = isPortUsing("127.0.0.1", port);} catch (Exception e) {}return flag;}/**** 測試主機Host的port端口是否被使用* @param host* @param port* @throws UnknownHostException*/public static boolean isPortUsing(String host,int port) {boolean flag = false;try {InetAddress Address = InetAddress.getByName(host);Socket socket = new Socket(Address,port); //建立一個Socket連接flag = true;} catch (IOException e) {//log.info(e.getMessage(),e);}return flag;}//start--end是所要檢測的端口范圍static int start=0;static int end=1024;/*** 由于本機上安裝了mysql,采用3306端口去驗證* @param args*/public static void main(String args[]){int testPost =3306;if(isLocalPortUsing(testPost)){System.out.println("端口 "+testPost+" 已被使用");}else{System.out.println("端口 "+testPost+"未使用");}} } public class ServerPortUtils {/*** 獲取可用端口* @return*/public static int getAvailablePort(){int max = 65535;int min = 2000;Random random = new Random();int port = random.nextInt(max)%(max-min +1) + min;boolean using = NetUtils.isLocalPortUsing(port);if(using){return getAvailablePort();}else{return port;}}}

項目啟動前設置server.port環境變量

/*** 開始命令*/ @Slf4j public class StartCommand {public StartCommand(String[] args){Boolean isServerPort = false;String serverPort = "";if(args != null){for (String arg:args){if(StringUtils.hasText(arg) &&arg.startsWith("--server.port")){isServerPort = true;serverPort = arg;break;}}}//沒有指定端口,則隨機生成一個可用的端口if(!isServerPort){int port = ServerPortUtils.getAvailablePort();log.info("current server.port=" + port);System.setProperty("server.port",String.valueOf(port));}else{//指定了端口,則以指定的端口為準log.info("current server.port=" + serverPort.split("=")[1]);System.setProperty("server.port",serverPort.split("=")[1]);}}}

啟動類調用方法:

@SpringBootApplication @EnableUserClient @RestController public class DemoApplication {@AutowiredEnvironment environment;public static void main(String[] args) {new StartCommand(args);SpringApplication.run(DemoApplication.class, args);} }

通過自定義PropertiesPropertySource屬性源實現

public class MyEnvironmentPostProcessor implements EnvironmentPostProcessor {@Overridepublic void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {//MapPropertySourceProperties properties = new Properties();properties.put("server.port", ServerPortUtils.getAvailablePort());System.out.println(properties.get("server.port"));PropertiesPropertySource source = new PropertiesPropertySource("myCustom", properties);environment.getPropertySources().addLast(source);//environment.getPropertySources().addAfter();} }

通過配置在resources/META-INF/spring.factories文件中使用全名注冊

org.springframework.boot.env.EnvironmentPostProcessor=com.laowan.demo.command.MyEnvironmentPostProcessor

這樣在項目啟動后,就會將該屬性源加載到Environment中。

server.port=0隨機端口 (推薦)

通過設置server.port=0,在spring boot項目啟動時,會自動去尋找一個空閑的端口,避免端口沖突。

擴展:server.port=-1

設置為-1是為了完全關閉HTTP端點,但仍創建一個WebApplicationContext, 主要是在單元測試時使用。

驗證: 執行單元測試,獲取server.port屬性

@SpringBootTest @Slf4j class DemoApplicationTests {@AutowiredEnvironment environment;@Testvoid getProperties() {System.out.println(environment.getProperty("server.port"));} }

執行結果為:-1

總結

  • 為什么要設置隨機端?主要是為了解決動態擴容時出現端口沖突的問題。
  • 怎么獲取一個有效的隨機端口號
  • spring boot下實現隨機端口的三種方式。關于方式三的自定義屬性源的實現方式可以多多品味,實踐一下,更好的體會屬性文件的加載順序。
  • 補充通過server.port=0,設置一個有效的隨機端口,推薦做法
  • 作者:斗者_2013
    原文鏈接:https://blog.csdn.net/w1014074794/article/details/106184883

    總結

    以上是生活随笔為你收集整理的3306端口_Spring Boot随机端口你都不会,怎么动态扩容?的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。