亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Spring boot隨機(jī)端口你都不會(huì)還怎么動(dòng)態(tài)擴(kuò)容

瀏覽:35日期:2023-05-16 17:32:08

一般情況下每個(gè)spring boot工程啟動(dòng)都有固定的端口,但是固定端口不利用服務(wù)的動(dòng)態(tài)擴(kuò)容,如果在一臺(tái)服務(wù)器上需要對(duì)同一個(gè)服務(wù)進(jìn)行多實(shí)例部署,很容易出現(xiàn)端口沖突,那么怎么解決這個(gè)問(wèn)題呢?

random隨機(jī)端口

在spring boot中,可以通過(guò)${random}來(lái)生成隨機(jī)數(shù)字,我們可以在配置文件中,這么設(shè)置端口:

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

通過(guò)random.int方法,指定生成2000~8000的隨機(jī)端口。這樣每次啟動(dòng)的端口都不一樣。

多次啟動(dòng),發(fā)現(xiàn)每次的端口都不一致說(shuō)明配置成功。

Spring boot隨機(jī)端口你都不會(huì)還怎么動(dòng)態(tài)擴(kuò)容

Spring boot隨機(jī)端口你都不會(huì)還怎么動(dòng)態(tài)擴(kuò)容

注意事項(xiàng):這里需要注意spring boot項(xiàng)目啟動(dòng)屬性文件的加載順序,spring boot的屬性是由里向外加載,所以最外層的最后被加載,會(huì)覆蓋里層的屬性。所以如果主動(dòng)在啟動(dòng)命令中使用?server.port配置了項(xiàng)目的端口號(hào),那么屬性文件中配置的隨機(jī)端口屬性就不會(huì)生效。

通過(guò)System.setProperty設(shè)置有效隨機(jī)端口

上面的方法雖然暫時(shí)達(dá)到了想要的效果,但是有個(gè)問(wèn)題:如果生成的這個(gè)隨機(jī)端口已經(jīng)被使用了,那么項(xiàng)目啟動(dòng)就會(huì)出現(xiàn)端口沖突。

那么,我們能否通過(guò)一個(gè)檢測(cè)機(jī)制,讓生成的隨機(jī)端口一定是一個(gè)沒(méi)有被占用的有效的隨機(jī)端口呢?

有效端口檢測(cè)原理:

通過(guò)建立socket連接,Socket socket = new Socket(Address,port);#address代表主機(jī)的IP地址,port代表端口號(hào)如果對(duì)該主機(jī)的特定端口號(hào)能建立一個(gè)socket,則說(shuō)明該主機(jī)的該端口在使用。Socket socket = new Socket(Address,port);#address代表主機(jī)的IP地址,port代表端口號(hào)如果對(duì)該主機(jī)的特定端口號(hào)能建立一個(gè)socket,則說(shuō)明該主機(jī)的該端口在使用。

實(shí)現(xiàn)思路:

通過(guò)在項(xiàng)目啟動(dòng)前,獲取有效的隨機(jī)端口并通過(guò)System.setProperty將變量設(shè)置到系統(tǒng)的全局變量中,這樣項(xiàng)目啟動(dòng)時(shí)就可以從全局變量中獲取到server.port變量的值。這里的system,系統(tǒng)指的是 JRE (runtime)system,即設(shè)置jvm運(yùn)行時(shí)的全局變量。

工具類:

@Slf4jpublic class NetUtils { /** * 測(cè)試本機(jī)端口是否被使用 * @param port * @return */ public static boolean isLocalPortUsing(int port){ boolean flag = true; try { //如果該端口還在使用則返回true,否則返回false,127.0.0.1代表本機(jī) flag = isPortUsing('127.0.0.1', port); } catch (Exception e) { } return flag; } /*** * 測(cè)試主機(jī)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); //建立一個(gè)Socket連接 flag = true; } catch (IOException e) { //log.info(e.getMessage(),e); } return flag; } //start--end是所要檢測(cè)的端口范圍 static int start=0; static int end=1024; /** * 由于本機(jī)上安裝了mysql,采用3306端口去驗(yàn)證 * @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; } }}

項(xiàng)目啟動(dòng)前設(shè)置server.port環(huán)境變量

/** * 開(kāi)始命令 */@Slf4jpublic 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; } } } //沒(méi)有指定端口,則隨機(jī)生成一個(gè)可用的端口 if(!isServerPort){ int port = ServerPortUtils.getAvailablePort(); log.info('current server.port=' + port); System.setProperty('server.port',String.valueOf(port)); }else{//指定了端口,則以指定的端口為準(zhǔn) log.info('current server.port=' + serverPort.split('=')[1]); System.setProperty('server.port',serverPort.split('=')[1]); } }}

啟動(dòng)類調(diào)用方法:

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

通過(guò)自定義PropertiesPropertySource屬性源實(shí)現(xiàn)

public class MyEnvironmentPostProcessor implements EnvironmentPostProcessor { @Override public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { //MapPropertySource Properties 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(); }}

通過(guò)配置在resources/META-INF/spring.factories文件中使用全名注冊(cè)

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

這樣在項(xiàng)目啟動(dòng)后,就會(huì)將該屬性源加載到Environment中。

Spring boot隨機(jī)端口你都不會(huì)還怎么動(dòng)態(tài)擴(kuò)容

總結(jié)

1、為什么要設(shè)置隨機(jī)端?主要是為了解決動(dòng)態(tài)擴(kuò)容時(shí)出現(xiàn)端口沖突的問(wèn)題。2、怎么獲取一個(gè)有效的隨機(jī)端口號(hào)3、spring boot下實(shí)現(xiàn)隨機(jī)端口的三種方式。關(guān)于方式三的自定義屬性源的實(shí)現(xiàn)方式可以多多品味,實(shí)踐一下,更好的體會(huì)屬性文件的加載順序。

到此這篇關(guān)于Spring boot隨機(jī)端口你都不會(huì)還怎么動(dòng)態(tài)擴(kuò)容的文章就介紹到這了,更多相關(guān)Spring boot隨機(jī)端口內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Spring
相關(guān)文章:
主站蜘蛛池模板: 国产一二三区四区乱码2021 | 人成精品视频三区二区一区 | 成年女人视频在线观看免费 | 亚洲美女在线播放 | 亚洲日本在线免费观看 | 日韩高清网站 | 国产夜色 | 九九精品久久久久久久久 | 免费看人做人爱视频拍拍拍 | 欧美久久xxxxxx影院 | 国产三级不卡 | 免费网站看v片在线香蕉 | 精品久久久影院 | 免费在线不卡视频 | 狠狠色噜噜狠狠狠狠97不卡 | 免费观看在线永久免费xx视频 | 久久久福利 | 爽爽影院色黄网站在线观看 | 黄色在线视频免费 | 免费国产成人高清视频网站 | 91福利在线免费观看 | 免费黄色在线视频观看 | 性欧美激情在线观看 | 国产这里有精品 | 激情毛片 | 日本免费黄色片 | 91三级视频 | 午夜影院性 | 久久永久免费视频 | 黄色免费在线观看网站 | 久久91精品国产91久久 | 日韩精品一区二区三区在线观看 | 亚洲免费视频播放 | a毛片在线观看 | 色天天综合色天天害人害己 | 香蕉婷婷 | 久久精品欧美一区二区 | 午夜黄色一级片 | 国产黄色一级大片 | 日韩精品一区二区三区中文字幕 | 三级理论中文字幕在线播放 |