Spring Cloud:多环境配置、eureka 安全认证、容器宿主机IP注册 | BNDong
0%

Spring Cloud:多环境配置、eureka 安全认证、容器宿主机IP注册

记录一下搭建 Spring Cloud 过程中踩过的一些坑,测试的东西断断续续已经弄了好多了,一直没有时间整理搭建过程,时间啊时间

Spring 版本

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

多环境配置切换

使用 Spring Cloud 来处理

多配置的切换在开发中真是很常用,能有效提高效率。一些成熟的框架基本都有关于配置切换的解决方案,当然了 Spring Cloud 也不例外!

先看看我的配置文件结构:

配置文件通过后缀区分:dev - 开发环境配置,test - 测试环境配置,prod - 生产环境配置。

bootstrap.yml 文件来配置加载那个配置文件:

1
2
3
spring:
profiles:
active: dev

spring.profiles.active 配置的就是需要加载的配置文件,这样就能通过配置来加载不同的配置文件。

这里说明一下配置的加载流程:bootstrap.yml —-> bootstrap-{profile}.yml —-> application.yml —-> application-{profile}.yml

也就是说,无论 bootstrap 还是 appliction 都可以做多环境配置切换的。

但是,我们一般都是打包成 jar 包来运行,这样分别打包还是有点麻烦,所以可以打包一个 jar 包,通过添加启动参数来加载不同的配置:

1
2
3
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 脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/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 项目,通过运行容器时候初始化一些环境变量来指定配置。

可以参考下面的文件了解一下:

docker-compose.yml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# 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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
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

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

配置文件增加 spring.security.user.namespring.security.user.password 配置,修改注册中心地址:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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

使用此组件,安全是实现了,访问注册中心页面,需要登录用户名和密码了,但是问题也出现了,客户端服务一直注册不上去。我查找资料给出的解决方案是禁用 securitycsrf,下面是处理方案,但是我使用此方案并不生效:

1
2
3
4
5
6
7
8
@EnableWebSecurity
static class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);//加这句是为了访问eureka控制台和/actuator时能做安全控制
http.csrf().disable();
}
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
################ 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地址):

1
2
3
4
5
6
7
8
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/

后记

写这篇随笔时候不知道为什么想到了看过的一个短片《断崖》,看的时候真的感受到了女主的绝望和无助。感觉自己就像女主一样,我在自己技术水平的坑里努力的爬着,好的是我爬出来了,坏的是外面还有一个更大的坑!!!人生路漫漫,且爬且珍惜!感谢阅读!

↓赏一个鸡腿... 要不,半个也行↓