Spring Cloud:多環境配置、eureka 安全認證、容器宿主機IP註冊

記錄一下搭建 Spring Cloud 過程當中踩過的一些坑,測試的東西斷斷續續已經弄了好多了,一直沒有時間整理搭建過程,時間啊~時間~

Spring 版本

  • Spring Boot:2.0.6.RELEASE
  • Spring Cloud:Finchley.SR2

多環境配置切換

使用 Spring Cloud 來處理

多配置的切換在開發中真是很經常使用,能有效提升效率。一些成熟的框架基本都有關於配置切換的解決方案,固然了 Spring Cloud 也不例外!java

先看看個人配置文件結構:node

配置文件經過後綴區分:dev - 開發環境配置,test - 測試環境配置,prod - 生產環境配置。git

bootstrap.yml 文件來配置加載那個配置文件:github

spring:
  profiles:
    active: dev

 spring.profiles.active 配置的就是須要加載的配置文件,這樣就能經過配置來加載不一樣的配置文件。web

這裏說明一下配置的加載流程:bootstrap.yml ----> bootstrap-{profile}.yml ----> application.yml ----> application-{profile}.ymlspring

也就是說,不管 bootstrap 仍是 appliction 均可以作多環境配置切換的。 docker

可是,咱們通常都是打包成 jar 包來運行,這樣分別打包仍是有點麻煩,因此能夠打包一個 jar 包,經過添加啓動參數來加載不一樣的配置:shell

java -jar xxx.jar --spring.profiles.active=dev 表示使用開發環境的配置
java -jar xxx.jar --spring.profiles.active=test 表示使用測試環境的配置
java -jar xxx.jar --spring.profiles.active=prod 表示使用生產環境的配置

這裏貼一個我封裝的啓動 jar 包的 shell 腳本:apache

#!/bin/bash
JAR_DIR='/data'
JAR_FILE=''
LOG_DIR='/dev/null'
CONF_ENV='dev'
JAR_NUM=1

if read -t 30 -p "Enter the jar storage directory(default: $JAR_DIR): " I_JAR_DIR
then

    if [ "$I_JAR_DIR" != "" ]
    then
        if [ ! -d "$I_JAR_DIR" ];then
            echo "Error: Directory does not exist;"
            exit 1
        fi
        JAR_DIR=$I_JAR_DIR
    fi

else
    echo
    echo "Error: Sorry, too slow"
    exit 1
fi

JAR_FILE_LIST=$(ls -1 $JAR_DIR | awk '/.*\.jar$/')
if [ "$JAR_FILE_LIST" = "" ]
then
    echo "Error: There is no runnable jar package"
    exit 1
else
    echo "--------------------------------------------------"
    echo "$JAR_FILE_LIST" | awk '/.*\.jar$/{print NR,$0}'
    echo "--------------------------------------------------"

    if read -t 30 -p "Enter the line number to run the jar package(default: $JAR_NUM): " I_JAR_NUM
    then
        if [ "$I_JAR_NUM" = "" ];then
            I_JAR_NUM=$JAR_NUM
        fi
        if [ ! -n "$(echo $I_JAR_NUM| sed -n "/^[0-9]\+$/p")" ] || [ $I_JAR_NUM -lt 1 ]
        then
            echo "Error: Illegal jar package line number"
            exit 1
        else
            JARSTR=$(echo "$JAR_FILE_LIST" | awk '{print $0 "|||"}')
            OLD_IFS="$IFS"
            IFS="|||"
            JAR_TEM=($JARSTR)
            IFS="$OLD_IFS"
            JAR_ARRAY=()
            JAR_ARRAY_i=1
            for var in ${JAR_TEM[@]}
            do
                if [ "$var" != "" ]
                then
                    JAR_ARRAY[$JAR_ARRAY_i]=$var
                    JAR_ARRAY_i=$(($JAR_ARRAY_i+1))
                fi
            done
            JAR_NUM=$I_JAR_NUM
        fi

    else
        echo
        echo "Error: Sorry, too slow"
        exit 1
    fi
fi

if read -t 30 -p "Enter the log storage directory(default: $LOG_DIR): " I_LOG_DIR
then

    if [ "$I_LOG_DIR" != "" ]
    then
        if [ ! -d "$I_LOG_DIR" ];then
            echo "Error: Directory does not exist;"
            exit 1
        fi
        LOG_DIR=$I_LOG_DIR
    fi

else
    echo
    echo "Error: Sorry, too slow"
    exit 1
fi

if read -t 30 -p "Input configuration environment(default: $CONF_ENV): " I_CONF_ENV
then

    if [ "$I_CONF_ENV" != "" ]
    then
        CONF_ENV=$I_CONF_ENV
    fi

else
    echo
    echo "Error: Sorry, too slow"
    exit 1
fi

ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

if [ "$LOG_DIR" != "/dev/null" ]
then
    LOG_URI=${LOG_DIR%*/}/${JAR_ARRAY[$JAR_NUM]}_"$CONF_ENV"_$(date "+%Y_%b_%d_%H_%M_%S_%N").txt
else
    LOG_URI=$LOG_DIR
fi
exec java -jar ${JAR_DIR%*/}/${JAR_ARRAY[$JAR_NUM]} > $LOG_URI --spring.profiles.active=$CONF_ENV &
echo "The successful running."

使用環境變量來處理

也有不少人選擇使用這種方式來處理,這主要是使用場景是使用 Docker 構建 Sprign 項目,經過運行容器時候初始化一些環境變量來指定配置。json

能夠參考下面的文件瞭解一下:

docker-compose.yml:

# local development configuration

version: '2.1'
services:
  standalone.eureka-develop:
    extends:
      service: base-eureka
      file: docker-compose-base.yml
    container_name: ${CONTAINER_HOST_NAME:-standalone.eureka}
    environment:
    - CONTAINER_HOST_NAME=${CONTAINER_HOST_NAME:-standalone.eureka}
    - EUREKA_CLIENT_FETCHREGISTRY=false
    - EUREKA_CLIENT_REGISTERWITHEUREKA=false
    - EUREKA_CLIENT_SERVICEURL_DEFAULTZONE=http://${SPRING_SECURITY_USER_NAME:-user}:${SPRING_SECURITY_USER_PASSWORD:-user_pass}@standalone.eureka:${SERVER_PORT:-8761}/eureka/
    #- EUREKA_INSTANCE_HOSTNAME=${CONTAINER_HOST_NAME:-standalone.eureka}
    - EUREKA_INSTANCE_IPADDRESS=${HOST_IPADDRESS:-172.16.238.10}


    - EUREKA_INSTANCE_REGISTRY_DEFAULTOPENFORTRAFFICCOUNT=${EUREKA_INSTANCE_REGISTRY_DEFAULTOPENFORTRAFFICCOUNT:-1}
    - EUREKA_SERVER_ENABLESELFPRESERVATION=${EUREKA_SERVER_ENABLESELFPRESERVATION:-true}
    - EUREKA_SERVER_RENEWALPERCENTTHRESHOLD=${EUREKA_SERVER_RENEWALPERCENTTHRESHOLD:-0.25}


    - SPRING_APPLICATION_NAME=standalone.eureka
    - SPRING_CLOUD_CLIENT_HOSTNAME=${CONTAINER_HOST_NAME:-standalone.eureka}
    - SPRING_CLOUD_CLIENT_IPADDRESS=${HOST_IPADDRESS:-172.16.238.10}
    - SPRING_PROFILES_ACTIVE=develop.env,manual_ip_hostname,port_nonsecure,standalone



    hostname: ${CONTAINER_HOST_NAME:-standalone.eureka}
    networks:
      local-network:
        ipv4_address: 172.16.238.10
        #ipv6_address: 2001:3984:3989::10
    ports:
    - "${SERVER_PORT:-8761}:${SERVER_PORT:-8761}"
    volumes:
    - data:/home/alpine/data
    - tmp:/tmp

networks:
  # docker network create --driver=bridge --ipam-driver=default --subnet=172.16.238.0/24 local-network
  # docker network ls
  # docker network inspect local-network
  local-network:
    external: true
    driver: bridge
    enable_ipv6: true
    ipam:
      driver: default
      config:
      - subnet: 172.16.238.0/24
      #- subnet: 2001:3984:3989::/64

volumes:
  data:
    driver: local
    driver_opts:
      type: none
      device: ${PWD}/data/data
      o: bind
  tmp:
    driver: local
    driver_opts:
      type: none
      device: ${PWD}/data/tmp
      o: bind

application.yml

eureka.client:
#  # Indicates whether server can redirect a client request to a backup server/cluster.
#  # If set to false, the server will handle the request directly,
#  # If set to true, it may send HTTP redirect to the client, with a new server location.
#  # default: false
#  allow-redirects: false
#  # Gets the list of availability zones (used in AWS data centers) for the region in which this instance resides.
#  # The changes are effective at runtime at the next registry fetch cycle as specified by registryFetchIntervalSeconds.
#  # default: <blank-value>
#  #availability-zones:
#  # Gets the name of the implementation which implements BackupRegistry to fetch the registry information
#  # as a fall back option for only the first time when the eureka client starts.
#  # This may be needed for applications which needs additional resiliency for registry information without which it cannot operate.
#  # default: <blank-value>
#  #backup-registry-impl:
#  # Cache refresh executor exponential back off related property.
#  # It is a maximum multiplier value for retry delay, in case where a sequence of timeouts occurred.
#  # default: 10
#  cache-refresh-executor-exponential-back-off-bound: 10
#  # The thread pool size for the cacheRefreshExecutor to initialise with
#  # default: 2
#  cache-refresh-executor-thread-pool-size: 2
#  # EurekaAccept name for client data accept
#  # default: <blank-value>
#  #client-data-accept:
#  # This is a transient config and once the latest codecs are stable, can be removed (as there will only be one)
#  # default: <blank-value>
#  #decoder-name:
#  # Indicates whether the eureka client should disable fetching of delta and should rather resort to getting the full registry information.
#  # Note that the delta fetches can reduce the traffic tremendously, because the rate of change with the eureka server is normally much lower than the rate of fetches.
#  # The changes are effective at runtime at the next registry fetch cycle as specified by registryFetchIntervalSeconds
#  # default: false
#  disable-delta: false
#  # Get a replacement string for Dollar sign <code>$</code> during serializing/deserializing information in eureka server.
#  # default: _-
#  #dollar-replacement: _-
#  # Flag to indicate that the Eureka client is enabled.
#  # default: true
#  #   client是否可用, 一般測試時不須要啓用真實服務時須要
#  enabled: true
#  # This is a transient config and once the latest codecs are stable, can be removed (as there will only be one)
#  # default: <blank-value>
#  #encoder-name:
#  # Get a replacement string for underscore sign <code>_</code> during serializing/deserializing information in eureka server.
#  # default: __
#  #escape-char-replacement: __
#  # Indicates how much time (in seconds) that the HTTP connections to eureka server can stay idle before it can be closed.
#  # In the AWS environment, it is recommended that the values is 30 seconds or less,
#  # since the firewall cleans up the connection information after a few mins leaving the connection hanging in limbo
#  # default: 30
#  #   單位s, 一個到Eureka的Http鏈接在關閉前能夠保持Idle狀態的最大時間
#  eureka-connection-idle-timeout-seconds: 30
#  # default eureka
#  eureka-server-u-r-l-context: eureka
#  # Indicates how long to wait (in seconds) before a connection to eureka server needs to timeout.
#  # Note that the connections in the client are pooled by org.apache.http.client.HttpClient and
#  # this setting affects the actual connection creation and also the wait time to get the connection from the pool.
#  # default: 5
#  eureka-server-connect-timeout-seconds: 5
#  # Gets the DNS name to be queried to get the list of eureka servers.
#  # This information is not required if the contract returns the service urls by implementing serviceUrls.
#  # The DNS mechanism is used when useDnsForFetchingServiceUrls is set to true and
#  # the eureka client expects the DNS to configured a certain way so that it can fetch changing eureka servers dynamically.
#  # The changes are effective at runtime.
#  # default: <blank-value>
#  #eureka-server-d-n-s-name:
#  # Gets the port to be used to construct the service url to contact eureka server when the list of eureka servers come from the DNS.
#  # This information is not required if the contract returns the service urls eurekaServerServiceUrls(String).
#  # The DNS mechanism is used when useDnsForFetchingServiceUrls is set to true and
#  # the eureka client expects the DNS to configured a certain way so that it can fetch changing eureka servers dynamically.
#  # The changes are effective at runtime.
#  # default: <blank-value>
#  #eureka-server-port:
#  # Indicates how long to wait (in seconds) before a read from eureka server needs to timeout.
#  # default: 8
#  #   單位s, 讀數據超時時長
#  eureka-server-read-timeout-seconds: 8
#  # Gets the total number of connections that is allowed from eureka client to all eureka servers.
#  # default: 200
#  #   Client到Eureka的最大鏈接數
#  eureka-server-total-connections: 200
#  # Gets the total number of connections that is allowed from eureka client to a eureka server host.
#  # default: 50
#  #   Client到單個Eureka的最大連接數
#  eureka-server-total-connections-per-host: 50
#  # Gets the URL context to be used to construct the service url to contact eureka server when the list of eureka servers come from the DNS.
#  # This information is not required if the contract returns the service urls from eurekaServerServiceUrls.
#  # The DNS mechanism is used when useDnsForFetchingServiceUrls is set to true and
#  # the eureka client expects the DNS to configured a certain way so that it can fetch changing eureka servers dynamically.
#  # The changes are effective at runtime.
#  # default: <blank-value>
#  #eureka-server-u-r-l-context:
#  # Indicates how often(in seconds) to poll for changes to eureka server information.
#  # Eureka servers could be added or removed and this setting controls how soon the eureka clients should know about it.
#  # default: 0
#  #   單位s, 客戶端拉取Eureka的狀態變化(Instances增刪)的時間間隔
#  eureka-service-url-poll-interval-seconds: 0
  # Indicates whether this client should fetch eureka registry information from eureka server.
  # default: true
  #   是否從Eureka獲取集羣Instances信息
  fetch-registry: ${EUREKA_CLIENT_FETCHREGISTRY:false}
#  # Comma separated list of regions for which the eureka registry information will be fetched.
#  # It is mandatory to define the availability zones for each of these regions as returned by availabilityZones.
#  # Failing to do so, will result in failure of discovery client startup.
#  # default: <blank-value>
#  #fetch-remote-regions-registry:
#  # Indicates whether to get the applications after filtering the applications for instances with only InstanceStatus UP states.
#  # default: true
#  #   是否只給出處於存活(UP)狀態的應用
#  filter-only-up-instances: true
#  # Indicates whether the content fetched from eureka server has to be compressed whenever it is supported by the server.
#  # The registry information from the eureka server is compressed for optimum network traffic.
#  # default: true
#  #   若是Eureka服務端支持, Client從Eureka獲取gzip壓縮過的數據
#  g-zip-content: true
  # see: https://github.com/spring-cloud/spring-cloud-netflix/blob/v1.4.4.RELEASE/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaDiscoveryClientConfiguration.java
  healthcheck.enabled: ${EUREKA_CLIENT_HEALTHCHECK_ENABLED:true}
#  # Heartbeat executor exponential back off related property.
#  # It is a maximum multiplier value for retry delay, in case where a sequence of timeouts occurred.
#  # default: 10
#  heartbeat-executor-exponential-back-off-bound: 10
#  # The thread pool size for the heartbeatExecutor to initialise with
#  # default: 2
#  #   向Eureka發送心跳的線程池大小
#  heartbeat-executor-thread-pool-size: 2
#  # Indicates how long initially (in seconds) to replicate instance info to the eureka server
#  # default: 40
#  #   單位s, 啓動後, 間隔多少時間後開始複製instance info到Eureka
#  initial-instance-info-replication-interval-seconds: 40
#  # Indicates how often(in seconds) to replicate instance changes to be replicated to the eureka server.
#  # default: 30
#  #   單位s, 每間隔多少時間複製instance info變更到Eureka
#  instance-info-replication-interval-seconds: 30
#  # Indicates whether to log differences between the eureka server and the eureka client in terms of registry information.
#  # Eureka client tries to retrieve only delta changes from eureka server to minimize network traffic.
#  # After receiving the deltas, eureka client reconciles the information from the server to verify it has not missed out some information.
#  # Reconciliation failures could happen when the client has had network issues communicating to server.
#  # If the reconciliation fails, eureka client gets the full registry information.
#  # While getting the full registry information, the eureka client can log the differences between the client and the server and this setting controls that.
#  # The changes are effective at runtime at the next registry fetch cycle as specified by registryFetchIntervalSecondsr
#  # default: false
#  #   是否記錄Eureka與Client之間關於註冊信息的差別
#  log-delta-diff: false
#  # If set to true, local status updates via ApplicationInfoManager will trigger on-demand (but rate limited) register/updates to remote eureka servers
#  # default: true
#  #   經過ApplicationInfoManager修改的狀態變化是否更新到Eureka
#  on-demand-update-status-change: true
#  # Indicates whether or not this instance should try to use the eureka server in the same zone for latency and/or other reason.
#  # Ideally eureka clients are configured to talk to servers in the same zone
#  # The changes are effective at runtime at the next registry fetch cycle as specified by registryFetchIntervalSeconds
#  # default: true
#  #   傾向使用於Client處在同一Zone內的Eureka
#  prefer-same-zone-eureka: true
#  # default: <blank-value>
#  #property-resolver:
#  # Gets the proxy host to eureka server if any.
#  # default: <blank-value>
#  #proxy-host:
#  # Gets the proxy password if any.
#  # default: <blank-value>
#  #roxy-password:
#  # Gets the proxy port to eureka server if any.
#  # default: <blank-value>
#  #proxy-port:
#  # Gets the proxy user name if any.
#  # default: <blank-value>
#  #proxy-user-name:
  # Gets the region (used in AWS datacenters) where this instance resides.
  # default: us-east-1
  region: ${EUREKA_CLIENT_REGION:us-east-1}
  # Indicates whether or not this instance should register its information with eureka server for discovery by others.
  # In some cases, you do not want your instances to be discovered whereas you just want do discover other instances.
  # default: true
  #   是否將服務發佈到Eureka
  register-with-eureka: ${EUREKA_CLIENT_REGISTERWITHEUREKA:false}
#  # Indicates how often(in seconds) to fetch the registry information from the eureka server.
#  # default: 30
#  #   單位s, 間隔多長時間從Eureka獲取註冊信息
#  registry-fetch-interval-seconds: 30
  # Indicates whether the client is only interested in the registry information for a single VIP.
  # default: <blank-value>
  #registry-refresh-single-vip-address:
  # Map of availability zone to list of fully qualified URLs to communicate with eureka server.
  # Each value can be a single URL or a comma separated list of alternative locations.
  # Typically the eureka server URLs carry protocol,host,port,context and version information if any.
  # Example: http://ec2-256-156-243-129.compute-1.amazonaws.com:7001/eureka/
  # The changes are effective at runtime at the next service url refresh cycle as specified by eurekaServiceUrlPollIntervalSeconds.
  # default: <blank-value>
  service-url:
    #   Note:
    #   Peer Awareness Mode: eureka.client.service-url.defaultZone's hosts affect DS Replicas value on dashboard
    #   Standalone Mode: Notice that the serviceUrl is pointing to the same host as the local instance.
    #   Note: must use 'defaultZone' here, otherwise cluster peers can not find replicas (can not see each other).
    #   split by comma
    defaultZone: ${EUREKA_CLIENT_SERVICEURL_DEFAULTZONE:http://${security.user.name:user}:${security.user.password:user_pass}@${EUREKA_INSTANCE_HOSTNAME:standalone.eureka}:${server.port}/eureka/}
#  # default: <blank-value>
#  #transport:
#  # Indicates whether the eureka client should use the DNS mechanism to fetch a list of eureka servers to talk to.
#  # When the DNS name is updated to have additional servers, that information is used immediately after
#  # the eureka client polls for that information as specified in eurekaServiceUrlPollIntervalSeconds.
#  # Alternatively, the service urls can be returned serviceUrls, but the users should implement their own mechanism to return the updated list in case of changes.
#  # The changes are effective at runtime.
#  # default: false
#  #use-dns-for-fetching-service-urls:

#eureka.dashboard:
#  # Flag to enable the Eureka dashboard. Default true.
#  # default: true
#  #   whether enable dashboard
#  enabled: true
#  # The path to the Eureka dashboard (relative to the servlet path). Defaults to "/".
#  # default: /
#  #   path of dashboard
#  path: /

eureka.instance:
#  # Gets the AWS autoscaling group name associated with this instance.
#  # This information is specifically used in an AWS environment to automatically put an instance out of service after the instance is launched and it has been disabled for traffic..
#  # default: <blank-value>
#  #a-s-g-name:
#  # Get the name of the application group to be registered with eureka.
#  # default: <blank-value>
#  #   application name on (register to) eureka
#  #app-group-name:
  # Get the name of the application to be registered with eureka.
  # default: unknown
  #   application name on (register to) eureka, all instances of an application must use same value
  appname: ${SPRING_APPLICATION_NAME:standalone.eureka}
#  # Returns the data center this instance is deployed. This information is used to get some AWS specific instance information if the instance is deployed in AWS.
#  # default: <blank-value>
#  #data-center-info:
#  # default: []
#  #default-address-resolution-order: []
#  # default: <blank-value>
#  #environment:
#  # Gets the relative health check URL path for this instance.
#  # The health check page URL is then constructed out of the hostname and the type of communication - secure or unsecure as specified in securePort and nonSecurePort.
#  # It is normally used for making educated decisions based on the health of the instance - for example,
#  # it can be used to determine whether to proceed deployments to an entire farm or stop the deployments without causing further damage.
#  #   健康檢查URL的ContextPath
#  # default: /health
#  health-check-url-path: /health
#  # Gets the absolute home page URL for this instance.
#  # The users can provide the homePageUrlPath if the home page resides in the same instance talking to eureka,
#  # else in the cases where the instance is a proxy for some other server, users can provide the full URL.
#  # If the full URL is provided it takes precedence.
#  # It is normally used for informational purposes for other services to use it as a landing page.
#  # The full URL should follow the format http://${eureka.hostname}:7001/ where the value ${eureka.hostname} is replaced at runtime.
#  # default: <blank-value>
#  #   instance's URL
#  #home-page-url:
#  # Gets the relative home page URL Path for this instance. The home page URL is then constructed out of the hostName and the type of communication - secure or unsecure.
#  # It is normally used for informational purposes for other services to use it as a landing page.
#  # default: /
#  #   instance's context-path
#  home-page-url-path: /
#  # default: <blank-value>
#  #host-info:
  # The hostname if it can be determined at configuration time (otherwise it will be guessed from OS primitives).
  # default: <blank-value>
  #   eureka.instance.hostname affect Status->instances's url href (not text) value on dashboard
  hostname: ${EUREKA_INSTANCE_HOSTNAME:${spring.cloud.client.hostname:standalone.eureka}}
#  # default: <blank-value>
#  #inet-utils:
#  # Initial status to register with remote Eureka server.
#  # default: <blank-value>
#  #   註冊到Eureka時的初始狀態
#  #initial-status:
#  # Indicates whether the instance should be enabled for taking traffic as soon as it is registered with eureka.
#  # Sometimes the application might need to do some pre-processing before it is ready to take traffic.
#  # default: false
#  #   實例註冊後是否能夠馬上提供服務, 一般註冊後在提供服務前還須要作些預處理
#  instance-enabled-onit: false
  # Get the IPAdress of the instance.
  # This information is for academic purposes only as
  # the communication from other instances primarily happen using the information supplied in {@link #getHostName(boolean)}.
  # default: <blank-value>
  #   若是未找到IP地址, 集羣結點間沒法互相註冊
  ip-address: ${EUREKA_INSTANCE_IPADDRESS:${spring.cloud.client.ip-address:127.0.0.1}}
#  # Indicates the time in seconds that the eureka server waits since it received the last heartbeat
#  # before it can remove this instance from its view and there by disallowing traffic to this instance.
#  # Setting this value too long could mean that the traffic could be routed to the instance
#  # even though the instance is not alive.
#  # Setting this value too small could mean, the instance may be taken out of traffic because of temporary network glitches.
#  # This value to be set to atleast higher than the value specified in leaseRenewalIntervalInSeconds.
#  # default: 90
#  #   單位s, 實例可被Eureka移除的秒數, 從Eureka最後一次收到實例心跳消息計算
#  lease-expiration-duration-in-seconds: 90
#  # Indicates how often (in seconds) the eureka client needs to send heartbeats to eureka server to indicate that it is still alive.
#  # If the heartbeats are not received for the period specified in leaseExpirationDurationInSeconds,
#  # eureka server will remove the instance from its view, there by disallowing traffic to this instance.
#  # Note that the instance could still not take traffic if it implements HealthCheckCallback and then decides to make itself unavailable.
#  # default: 30
#  #   單位s, Client發送心跳的時間間隔
#  lease-renewal-interval-in-seconds: 30
#  # Get the namespace used to find properties. Ignored in Spring Cloud.
#  # default: eureka
#  #   查找屬性時使用的名稱空間, spring-cloud中已忽略
#  namespace: eureka
  # Flag to say that, when guessing a hostname, the IP address of the server should be used in preference to the hostname reported by the OS.
  # default: false
  #   當猜想hostname時, 是否優先使用IP地址
  prefer-ip-address: ${EUREKA_INSTANCE_PREFERIPADDRESS:false}
#  registry:
#    # Value used in determining when leases are cancelled, default to 1 for standalone. Should be set to 0 for peer replicated eurekas
#    # default: 1
#    default-open-for-traffic-count: ${EUREKA_INSTANCE_REGISTRY_DEFAULTOPENFORTRAFFICCOUNT:1}
#    # default: 1
#    expected-number-of-renews-per-min: 1
#  # Gets the absolute status page URL path for this instance.
#  # The users can provide the statusPageUrlPath if the status page resides in the same instance talking to eureka,
#  # else in the cases where the instance is a proxy for some other server, users can provide the full URL.
#  # If the full URL is provided it takes precedence.
#  # It is normally used for informational purposes for other services to find about the status of this instance.
#  # Users can provide a simple HTML indicating what is the current status of the instance.
#  # default: <blank-value>
#  #   狀態頁URL, 到Root級別
#  #status-page-url:
#  # Gets the relative status page URL path for this instance.
#  # The status page URL is then constructed out of the hostName and the type of communication - secure or unsecure as specified in securePort and nonSecurePort.
#  # It is normally used for informational purposes for other services to find about the status of this instance.
#  # Users can provide a simple HTML indicating what is the current status of the instance.
#  # default: /info
#  #   狀態頁URL的ContextPath
#  status-page-url-path: /info

eureka.server:
#  a-s-g-cache-expiry-timeout-ms: 0
#  a-s-g-query-timeout-ms: 300
#  a-s-g-update-interval-ms: 0
#  a-w-s-access-id:
#  a-w-s-secret-key:
#  #   是否批量複製
#  batch-replication: false
#  binding-strategy:
#  #   Non-positive
#  #delta-retention-timer-interval-in-ms: 0
#  disable-delta: false
#  disable-delta-for-remote-regions: false
#  disable-transparent-fallback-to-other-region: false
#  e-i-p-bind-rebind-retries: 3
#  e-i-p-binding-retry-interval-ms: 0
#  e-i-p-binding-retry-interval-ms-when-unbound: 0
#  enable-replicated-request-compression: false
  enable-self-preservation: ${EUREKA_SERVER_ENABLESELFPRESERVATION:true}
#  #   Non-positive
#  #eviction-interval-timer-in-ms: 0
#  g-zip-content-from-remote-region: true
#  json-codec-name:
#  list-auto-scaling-groups-role-name: ListAutoScalingGroups
#  log-identity-headers: true
#  max-elements-in-peer-replication-pool: 10000
#  max-elements-in-status-replication-pool: 10000
#  #   單位分鐘, 節點間負責複製信息的線程的最大空閒時間
#  max-idle-thread-age-in-minutes-for-peer-replication: 15
#  #   單位分鐘, 節點間負責複製status的線程的最大空閒時間
#  max-idle-thread-in-minutes-age-for-status-replication: 10
#  #   複製信息的最大線程數
#  max-threads-for-peer-replication: 20
#  #   複製status的最大線程數
#  max-threads-for-status-replication: 1
#  #   複製信息的最大時長
#  max-time-for-replication: 30000
#  #   複製信息的最小線程數
#  min-threads-for-peer-replication: 5
#  #   複製status的最小線程數
#  min-threads-for-status-replication: 1
#  number-of-replication-retries: 5
#  #   Non-positive
#  #peer-eureka-nodes-update-interval-ms: 0
#  #   Non-positive
#  #peer-eureka-status-refresh-time-interval-ms: 0
#  #   單位ms, 節點間鏈接超時
#  peer-node-connect-timeout-ms: 200
#  #   單位s, 節點間鏈接空閒超時
#  peer-node-connection-idle-timeout-seconds: 30
#  #   單位ms, 節點間read超時
#  peer-node-read-timeout-ms: 200
#  #   節點總鏈接數上限
#  peer-node-total-connections: 1000
#  #   節點與單個主機之間的鏈接數上限
#  peer-node-total-connections-per-host: 500
#  prime-aws-replica-connections: true
#  #   org.springframework.core.env.PropertyResolver
#  #property-resolver:
#  rate-limiter-burst-size: 10
#  rate-limiter-enabled: false
#  rate-limiter-full-fetch-average-rate: 100
#  rate-limiter-privileged-clients:
#  rate-limiter-registry-fetch-average-rate: 500
#  rate-limiter-throttle-standard-clients: false
#  registry-sync-retries: 0
#  registry-sync-retry-wait-ms: 0
#  #   a map
#  #remote-region-app-whitelist:
#  remote-region-connect-timeout-ms: 1000
#  remote-region-connection-idle-timeout-seconds: 30
#  remote-region-fetch-thread-pool-size: 20
#  remote-region-read-timeout-ms: 1000
#  remote-region-registry-fetch-interval: 30
#  remote-region-total-connections: 1000
#  remote-region-total-connections-per-host: 500
#  remote-region-trust-store:
#  remote-region-trust-store-password: changeit
#  remote-region-urls:
#  #   a map
#  #remote-region-urls-with-name:
  renewal-percent-threshold: ${EUREKA_SERVER_RENEWALPERCENTTHRESHOLD:0.25}
#  #   Non-positive
#  #renewal-threshold-update-interval-ms: 0
#  response-cache-auto-expiration-in-seconds: 180
#  #   Non-positive
#  #response-cache-update-interval-ms: 0
#  retention-time-in-m-s-in-delta-queue: 0
#  route53-bind-rebind-retries: 3
#  route53-binding-retry-interval-ms: 0
#  route53-domain-t-t-l: 30
#  sync-when-timestamp-differs: true
#  use-read-only-response-cache: true
#  wait-time-in-ms-when-sync-empty: 0 # set to 0 will break cluster
#  xml-codec-name:

logging:
  config: classpath:log4j2-spring.xml
  #file: ${LOG_FILE:${CONTAINER_HOST_NAME:${spring.cloud.client.hostname:${spring.application.name}-${server.port}}}}.log
  #path: ${LOG_PATH:${user.dir}/data/logs/${spring.application.name}}
  level:
    jndi: ${LOGGING_LEVEL_ROOT:INFO}

    org.springframework.beans.factory.annotation.InjectionMetadata: ${LOGGING_LEVEL_ROOT:INFO}
    org.springframework.beans.factory.support.DefaultListableBeanFactory: ${LOGGING_LEVEL_ROOT:INFO}
    org.springframework.core.env.MutablePropertySources: ${LOGGING_LEVEL_ROOT:INFO}
    org.springframework.core.env.PropertySourcesPropertyResolver: ${LOGGING_LEVEL_ROOT:INFO}
    org.springframework.jndi: ${LOGGING_LEVEL_ROOT:INFO}
    org.springframework.core.type.classreading.AnnotationAttributesReadingVisitor: INFO
    org.springframework.web.context.support.StandardServletEnvironment: ${LOGGING_LEVEL_ROOT:INFO}
    org.springframework.security: ${LOGGING_LEVEL_ROOT:INFO}
    root: ${LOGGING_LEVEL_ROOT:INFO}

management:
  endpoint:
    shutdown.enabled: ${MANAGEMENT_ENDPOINT_SHUTDOWN_ENABLED:true}
    health:
      show-details: ${MANAGEMENT_ENDPOINT_HEALTH_SHOWDETAILS:WHEN_AUTHORIZED}
      roles: ${MANAGEMENT_ENDPOINT_HEALTH_ROLES:ACTUATOR}
  endpoints:
    web: # since spring-boot 2.x
      base-path: ${MANAGEMENT_ENDPOINTS_WEB_BASEPATH:/} # default: /actuator, management.context-path deprecated since spring-boot 2.x
      exposure:
        include: "${MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE:*}"
        exclude: "${MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_EXCLUDE:}"

server.port: ${SERVER_PORT:8761}

spring:
  aop.auto: false
  application:
    # every instance in cluster must ues same spring.application.name
    # Peer Awareness Mode: 'eureka-cluster'
    # Standalone Mode: 'standalone.eureka'
    name: ${SPRING_APPLICATION_NAME:standalone.eureka}
    # bug: https://github.com/spring-cloud/spring-cloud-netflix/issues/788
  cloud:
    inetutils:
      preferred-networks: ${SPRING_CLOUD_INETUTILS_PREFERREDNETWORKS:^192\.168\..+, ^172\.30\..+, ^10\..+}
      ignored-interfaces: ${SPRING_CLOUD_INETUTILS_IGNOREDINTERFACES:^[a-z]?tun[0-9]*, ^awdl[0-9]*, ^lo[0-9]*}

  security:
    enabled: ${SPRING_SECURITY_ENABLED:false}
    user:
      name: ${SPRING_SECURITY_USER_NAME:user}
      password: ${SPRING_SECURITY_USER_PASSWORD:user_pass}
      roles: ${SPRING_SECURITY_USER_ROLES:ACTUATOR, ADMIN, SUPERUSER, USER}


---
spring:
  profiles: port_nonsecure

eureka.instance:
#  # Get the unique Id (within the scope of the appName) of this instance to be registered with eureka.
#  # default: <blank-value>
#  #   instance的id, 區分同一應用的不一樣實例
#  #   eureka.instance.instance-id affect Status->instances's url text (not href) value on dashboard
#  #   or spring.cloud.client.ip-address if eureka.instance.prefer-ip-address=true
#  #   other possible values:
#  #     ${spring.application.name}:${spring.cloud.client.ip-address}:${EUREKA_INSTANCE_NONSECUREPORT:${SERVER_PORT:8761}}:${random.value}
#  #     ${spring.application.name}:${spring.cloud.client.hostname}:${EUREKA_INSTANCE_NONSECUREPORT:${SERVER_PORT:8761}}:${random.value}
#  instance-id: ${spring.application.name}:${spring.cloud.client.hostname}:${EUREKA_INSTANCE_NONSECUREPORT:${SERVER_PORT:8761}}:${random.value}
#  # Gets the absolute health check page URL for this instance.
#  # The users can provide the healthCheckUrlPath if the health check page resides in the same instance talking to eureka,
#  # else in the cases where the instance is a proxy for some other server, users can provide the full URL. If the full URL is provided it takes precedence.
#  # It is normally used for making educated decisions based on the health of the instance - for example,
#  # it can be used to determine whether to proceed deployments to an entire farm or stop the deployments without causing further damage.
#  # The full URL should follow the format http://${eureka.hostname}:7001/ where the value ${eureka.hostname} is replaced at runtime.
#  # default: <blank-value>
#  #   健康檢查URL, 到Root級別(HTTP)
#  health-check-url: ${EUREKA_INSTANCE_HEALTHCHECKURL:}
#  # Gets the metadata name/value pairs associated with this instance. This information is sent to eureka server and can be used by other instances.
#  # default: <blank-value>
#  #   實例元數據
#  #metadataMap:
#    #hostname: ${EUREKA_INSTANCE_HOSTNAME:standalone.eureka}
#    #prot: ${EUREKA_INSTANCE_NONSECUREPORT:8761}
#    #instanceId: ${spring.cloud.client.hostname}:${spring.application.name}:${EUREKA_INSTANCE_NONSECUREPORT:${SERVER_PORT:8761}}
#    # or spring.cloud.client.ip-address if eureka.instance.prefer-ip-address=true
#    #instanceId: ${spring.cloud.client.ip-address}:${spring.application.name}:${EUREKA_INSTANCE_NONSECUREPORT:${SERVER_PORT:8761}}
  # Get the non-secure port on which the instance should receive traffic.
  # default: 80
  #   eureka.instance.non-secure-port affect Status->instances's url href (not text) value on dashboard
  non-secure-port: ${EUREKA_INSTANCE_NONSECUREPORT:8761}
  # Indicates whether the non-secure port should be enabled for traffic or not.
  # default: true
  non-secure-port-enabled: true
  # Gets the virtual host name defined for this instance.
  # This is typically the way other instance would find this instance by using the virtual host name.
  # Think of this as similar to the fully qualified domain name, that the users of your services will need to find this instance.
  # default: unknown
  #virtual-host-name: unknown
  secure-port-enabled: false

---
spring:
  profiles: port_secure

eureka.instance:
  non-secure-port-enabled: false
#  instance-id: ${spring.cloud.client.hostname}:${spring.application.name}:${EUREKA_INSTANCE_SECUREPORT:${SERVER_PORT:8761}}:${random.value}
#  # Gets the absolute secure health check page URL for this instance.
#  # The users can provide the secureHealthCheckUrl if the health check page resides in the same instance talking to eureka,
#  # else in the cases where the instance is a proxy for some other server, users can provide the full URL.
#  # If the full URL is provided it takes precedence.
#  # It is normally used for making educated decisions based on the health of the instance - for example,
#  # it can be used to determine whether to proceed deployments to an entire farm or stop the deployments without causing further damage.
#  # The full URL should follow the format http://${eureka.hostname}:7001/ where the value ${eureka.hostname} is replaced at runtime.
#  # default: <blank-value>
#  #   健康檢查URL, 到Root級別(HTTPS)
#  secure-health-check-url: ${EUREKA_INSTANCE_SECUREHEALTHCHECKURL:}
  # Indicates whether the secure port should be enabled for traffic or not.
  # default: false
  #   是否啓用HTTPS
  secure-port-enabled: true
  # Get the Secure port on which the instance should receive traffic.
  # default: 443
  #   HTTPS端口
  secure-port: ${EUREKA_INSTANCE_SECUREPORT:8761}
  # Gets the secure virtual host name defined for this instance.
  # This is typically the way other instance would find this instance by using the secure virtual host name.
  # Think of this as similar to the fully qualified domain name, that the users of your services will need to find this instance.
  # default: unknown
  #secure-virtual-host-name: unknown

---
spring:
  profiles: manual_ip_hostname

spring.cloud:
  client:
    hostname: ${SPRING_CLOUD_CLIENT_HOSTNAME:}
    ip-address: ${SPRING_CLOUD_CLIENT_IPADDRESS:}

---
spring:
  profiles: peer_awareness

spring.application:
  name: ${SPRING_APPLICATION_NAME:eureka-cluster}

eureka.client:
  fetch-registry: ${EUREKA_CLIENT_FETCHREGISTRY:true}
  register-with-eureka: ${EUREKA_CLIENT_REGISTERWITHEUREKA:true}

eureka.instance:
  appname: ${SPRING_APPLICATION_NAME:eureka-cluster}

---
spring:
  profiles: standalone

spring.application:
  name: ${SPRING_APPLICATION_NAME:standalone.eureka}

eureka.client:
  fetch-registry: ${EUREKA_CLIENT_FETCHREGISTRY:false}
  register-with-eureka: ${EUREKA_CLIENT_REGISTERWITHEUREKA:false}

eureka.instance:
  appname: ${SPRING_APPLICATION_NAME:standalone.eureka}

---
spring.profiles: develop.env

---
spring.profiles: it.env

---
spring.profiles: staging.env

---
spring.profiles: production.env
#spring.profiles.include:
#- port.nonsecure

使用這種方式的優缺點

優勢:

  • 這種方法使容器在配置方面更具動態性。
  • 集羣能夠共用一個JAR包來運行,經過容器來配置。

缺點:

  • 在單容器中配置是固定的,沒法便捷的切換。

註冊中心安全認證

註冊中心的頁面是直接就能訪問的,這確定不是咱們所但願的,因此須要添加安全機制進行保護,這裏須要用到依賴 spring-boot-starter-security 

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

配置文件增長 spring.security.user.name 和 spring.security.user.password 配置,修改註冊中心地址:

eureka:
  client:
    service-url:
      defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@192.168.1.254:9010/eureka/ # 註冊中心地址
    register-with-eureka: false # 是否註冊到註冊中心
    fetch-registry: false # 是否拉取服務列表
  server:
    enable-self-preservation: true # 是否開啓註冊中心保護機制
    eviction-interval-timer-in-ms: 60000 # 服務清理間隔,毫秒
  instance:
    prefer-ip-address: true # 是否使用IP地址廣播服務
    lease-renewal-interval-in-seconds: 30 # 服務租約時間,秒
    lease-expiration-duration-in-seconds: 90 # 間隔多久時間沒有發送心跳,認爲服務不可用,秒

spring:
  # 服務設置
  application:
    name: server-eureka
  # 安全機制
  security:
    user:
      name: eureka
      password: 123456

# 服務設置
server:
  port: 9010

使用此組件,安全是實現了,訪問註冊中心頁面,須要登陸用戶名和密碼了,可是問題也出現了,客戶端服務一直註冊不上去。我查找資料給出的解決方案是禁用 security 的 csrf,下面是處理方案,可是我使用此方案並不生效

@EnableWebSecurity
    static class WebSecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            super.configure(http);//加這句是爲了訪問eureka控制檯和/actuator時能作安全控制
            http.csrf().disable();
        }
    }

上面的方案我使用不生效,我使用下面的方案解決的:

package com.microview.servereureka.basic;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;

/**
 * 註冊中心basic認證
 */
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Value("${spring.security.user.name}")
    private String username;

    @Value("${spring.security.user.password}")
    private String password;

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .passwordEncoder(NoOpPasswordEncoder.getInstance())
                .withUser(username).password(password)
                .authorities("ADMIN");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf()
                .disable()
                .authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .httpBasic();
    }
}

容器宿主機IP註冊

因爲全部的項目都運行在 Docker 容器中,這就致使客戶端註冊到註冊中心的 IP 地址爲容器的虛擬 IP,沒法經過外部訪問,這裏的解決方案是構建容器時候設置容器的網絡模式爲橋接模式。

docker-compose.yml 中配置 network_mode: "bridge" 

  ################ spring-cloud-eureka ##############
  cloud_eureka:
    image: ${REGISTRY_URL}/${REGISTRY_NAMESPACE}/${CLOUD_EUREKA_NAME}:${CLOUD_EUREKA_VERSION}
    container_name: ${CLOUD_EUREKA_CONTAINER_NAME}
    hostname: ${CLOUD_EUREKA_CONTAINER_NAME}
    ports:
    - "${CLOUD_EUREKA_PORT}:9010"
    volumes:
    - ${CLOUD_EUREKA_DATA}:/data/:rw
    - ${CLOUD_EUREKA_LOGS}:/data/logs/:rw
    - ${SH_DIR}:/usr/local/sh/:rw
    tty: true
    restart: always
    network_mode: "bridge"

客戶端配置文件中相關配置(192.168.1.254 爲宿主機IP地址):

eureka:
  client:
    service-url:
      defaultZone: http://eureka:123456@192.168.1.254:9010/eureka/
  instance:
    instance-id: ${eureka.instance.ip-address}:${server.port}
    ip-address: 192.168.1.254
    prefer-ip-address: true

這樣註冊到註冊中心的IP地址就是宿主機的IP了。

同主機多 eureka 須要特別注意:eureka 註冊地址主機相同(相同的IP地址或 hostname)不會互相同步註冊信息。

 

my spring cloud exampleshttps://github.com/BNDong/spring-cloud-examples

參考資料

https://blog.csdn.net/quanqxj/article/details/80592231

https://github.com/spring-cloud/spring-cloud-netflix/issues/2754

https://www.oschina.net/question/556985_2273961

https://blog.csdn.net/qq_36148847/article/details/79427878

https://www.youtube.com/watch?v=tFw8Nm8meqI

https://dantehranian.wordpress.com/2015/03/25/how-should-i-get-application-configuration-into-my-docker-containers/

後記

寫這篇隨筆時候不知道爲何想到了看過的一個短片《斷崖》,看的時候真的感覺到了女主的絕望和無助。感受本身就像女主同樣,我在本身技術水平的坑裏努力的爬着,好的是我爬出來了,壞的是外面還有一個更大的坑!!!人生路漫漫,且爬且珍惜!感謝閱讀!

相關文章
相關標籤/搜索