欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring boot隨機端口你都不會還怎么動態(tài)擴容

 更新時間:2020年05月19日 09:34:45   作者:斗者_2013  
這篇文章主要介紹了Spring boot隨機端口你都不會還怎么動態(tài)擴容,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

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

random隨機端口

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

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

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

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



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

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

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

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

有效端口檢測原理:

通過建立socket連接,Socket socket = new Socket(Address,port);#address代表主機的IP地址,port代表端口號
如果對該主機的特定端口號能建立一個socket,則說明該主機的該端口在使用。
Socket socket = new Socket(Address,port);#address代表主機的IP地址,port代表端口號
如果對該主機的特定端口號能建立一個socket,則說明該主機的該端口在使用。

實現(xiàn)思路:

通過在項目啟動前,獲取有效的隨機端口并通過System.setProperty將變量設置到系統(tǒng)的全局變量中,這樣項目啟動時就可以從全局變量中獲取到server.port變量的值。
這里的system,系統(tǒng)指的是 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環(huán)境變量

/**
 * 開始命令
 */
@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 {
  @Autowired
  Environment environment;

  public static void main(String[] args) {
    new StartCommand(args);
    SpringApplication.run(DemoApplication.class, args);
  }
}

通過自定義PropertiesPropertySource屬性源實現(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();
  }
}

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

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

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

總結

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

到此這篇關于Spring boot隨機端口你都不會還怎么動態(tài)擴容的文章就介紹到這了,更多相關Spring boot隨機端口內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java基礎之教你如何正確運用依賴注入

    Java基礎之教你如何正確運用依賴注入

    最近發(fā)現(xiàn)很多使用Spring框架的Java代碼存在依賴注入方式的誤用,甚至是濫用.因此整理了這篇文章,歡迎大家一起探討,需要的朋友可以參考下
    2021-05-05
  • Spring框架接入單機Redis兩種實現(xiàn)方式解析

    Spring框架接入單機Redis兩種實現(xiàn)方式解析

    這篇文章主要介紹了Spring框架接入單機Redis兩種實現(xiàn)方式解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-09-09
  • 詳解利用SpringCloud搭建一個最簡單的微服務框架

    詳解利用SpringCloud搭建一個最簡單的微服務框架

    這篇文章主要介紹了詳解利用SpringCloud搭建一個最簡單的微服務框架,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • java簡單實現(xiàn)復制 粘貼 剪切功能代碼分享

    java簡單實現(xiàn)復制 粘貼 剪切功能代碼分享

    本文給大家分享了一段java編寫的簡單實現(xiàn)復制粘貼剪切功能的代碼,需要的小伙伴可以直接拿走使用。如有更好的方案,也可以告之本人。
    2014-11-11
  • Spring AOP中使用args表達式的方法示例

    Spring AOP中使用args表達式的方法示例

    這篇文章主要介紹了Spring AOP中使用args表達式的方法,結合實例形式分析了spring面向切面AOP中使用args表達式具體步驟、相關實現(xiàn)技巧與操作注意事項,需要的朋友可以參考下
    2020-01-01
  • Spring深入刨析聲明式事務

    Spring深入刨析聲明式事務

    在spring注解中,使用聲明式事務,需要用到兩個核心的注解:@Transactional注解和@EnableTransactionManagement注解。將@Transactional注解加在方法上,@EnableTransactionManagement注解加在配置類上
    2022-12-12
  • MybatisPlus?構造器wrapper的使用與原理解析

    MybatisPlus?構造器wrapper的使用與原理解析

    本次我們介紹了MybatisPlus?構造器wrapper的使用方式及其易錯點,同時也針對其運行的原理進行了解釋,只有深刻理解了它的原理,我們才能更靈活的使用,并且更快的排查出問題,感興趣的朋友跟隨小編一起看看吧
    2024-05-05
  • IDEA SSM框架整合配置及步驟詳解

    IDEA SSM框架整合配置及步驟詳解

    這篇文章主要介紹了IDEA SSM框架整合配置以及步驟,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • 一文精通Java 多線程之全方位解讀

    一文精通Java 多線程之全方位解讀

    Java 給多線程編程提供了內置的支持。 一條線程指的是進程中一個單一順序的控制流,一個進程中可以并發(fā)多個線程,每條線程并行執(zhí)行不同的任務,多線程是多任務的一種特別的形式,但多線程使用了更小的資源開銷
    2021-10-10
  • java實現(xiàn)學生宿舍系統(tǒng)

    java實現(xiàn)學生宿舍系統(tǒng)

    這篇文章主要為大家詳細介紹了java實現(xiàn)學生宿舍系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03

最新評論