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

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

Spring 版本

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

多环境配置

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

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

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

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

spring:
  profiles:
    active: dev

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

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

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 脚本:

#!/bin/bash
JARURI=$1 # 第一个参数为jar包绝对路径
CONFENV=$2 # 第二个参数为配置环境
LOGSDIR=$3 # 第三个参数为日志目录

# 判断文件是否存在
if [ ! -f "$JARURI" ];then
    echo "ERROR:File does not exist;"
    exit 1
fi

# 判断日志目录是否存在
if [ ! -d "$LOGSDIR" ];then
    echo "ERROR:Directory does not exist;"
    exit 1
fi

# 判断配置环境
ENVARR=("dev" "test" "prod")
if echo "${ENVARR[@]}" | grep -w "$CONFENV" &>/dev/null; then
    :
else
    echo "ERROR:Env does not exist;"
    exit 1
fi

# 启动
OLD_IFS="$IFS"
IFS="/"
file_array=($JARURI)
IFS="$OLD_IFS"
file_array_len=${#file_array[*]}
file_name_index=`expr $file_array_len - 1`
log_uri=${LOGSDIR%*/}/${file_array[$file_name_index]}_"$CONFENV"_$(date "+%Y_%b_%d_%H_%M_%S_%N").txt
java -jar $JARURI > $log_uri --spring.profiles.active=$CONFENV &

注册中心安全认证

注册中心的页面是直接就能访问的,这肯定不是我们所希望的,所以需要添加安全机制进行保护,这里需要用到依赖 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"

客户端配置文件中相关配置(192.168.1.254 为宿主机IP地址):

eureka:
  client:
    service-url:
      defaultZone: http://eureka:[email protected]:9010/eureka/
  instance:
    instance-id: ${eureka.instance.ip-address}:${server.port}
    ip-address: 192.168.1.254
    prefer-ip-address: true

这样注册到注册中心的IP地址就是宿主机的IP了。

参考资料

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.cnblogs.com/bndong/p/10037197.html

时间: 2024-08-01 15:27:35

Spring Cloud:多环境配置、注册中心安全认证、容器宿主机IP注册的相关文章

跟我学SpringCloud | 第六篇:Spring Cloud Config Github配置中心

SpringCloud系列教程 | 第六篇:Spring Cloud Config Github配置中心 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如无特殊说明,本系列教程全采用以上版本 随着分布式项目越来越大,勤劳的程序猿们会开始面临一个挑战,配置文件会越来越繁杂,虽然spring提供了一个鸡肋版的解决方案,spring.profiles.active,在大型的分布式项目体系中,聊胜于无吧,手动维护配置文件的痛苦,生产,UAT,测

Spring Cloud Gateway 结合配置中心限流

前言 假设你领导给你安排了一个任务,具体需求如下: 针对具体的接口做限流 不同接口限流的力度可以不同 可以动态调整限流配置,实时生效 如果你接到上面的任务,你会怎么去设计+实现呢? 每个人看待问题的角度不同,自然思考出来的方案也不同,正所谓条条大路通罗马,能到达目的地的路那就是一条好路. 如何分析需求 下面我给出我的实现方式,仅供各位参考,大牛请忽略. 具体问题具体分析,针对需求点,分别去做分析. 需求一 "如何针对具体的接口做限流" 这个在上篇文章中也有讲过,只需要让KeyResol

idea spring+springmvc+mybatis环境配置整合详解

idea spring+springmvc+mybatis环境配置整合详解 1.配置整合前所需准备的环境: 1.1:jdk1.8 1.2:idea2017.1.5 1.3:Maven 3.5.2 2.查看idea中是否安装Maven插件: 2.1:File --> Settings --> Plugins 2.2:如下图所示的步骤进行操作(注:安装完插件,idea会重新启动) 3.idea创建Maven项目的步骤 4.搭建目录结构 下图就是我搭建Maven项目之后,添加对应的目录和文件 5.p

12. Dubbo原理解析-注册中心之基于dubbo协议的简单注册中心实现

基于dubbo协议开源只是给出了默认一个注册中心实现SimpleRegistryService, 它只是一个简单实现,不支持集群,就是利用Map<String/*ip:port*/, Map<String/*service*/, URL>来存储服务地址, 具体不在啰嗦了,请读者翻看源代码,可作为自定义注册中的参考. 注册中心启动 SimpleRegistryService本身也是作为一个dubbo服务暴露. <dubbo:protocolport="9090"

spring cloud 搭建(配置中心)

创建配置中心: 选择Spring Initializr模板 选择Config Server pom文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schema

Spring Cloud Config 分布式配置中心使用教程

一.简介 在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件.在Spring Cloud中,有分布式配置中心组件spring cloud config ,它支持配置服务放在配置服务的内存中(即本地),也支持放在远程Git仓库中.在spring cloud config 组件中,分两个角色,一是config server,二是config client. 二.构建Config Server 创建一个spring-boot项目,取名为config-s

构建微服务架构Spring Cloud:分布式配置中心

Spring Cloud Config是Spring Cloud团队创建的一个全新项目,用来为分布式系统中的基础设施和微服务应用提供集中化的外部配置支持,它分为服务端与客户端两个部分.其中服务端也称为分布式配置中心,它是一个独立的微服务应用,用来连接配置仓库并为客户端提供获取配置信息.加密/解密信息等访问接口:而客户端则是微服务架构中的各个微服务应用或基础设施,它们通过指定的配置中心来管理应用资源与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息.Spring Cloud Conf

Spring Cloud Config分布式配置中心的使用和遇到的坑

分布式配置中心 为什么要有用分布式配置中心这玩意儿?现在这微服务大军已经覆盖了各种大小型企业,每个服务的粒度相对较小,因此系统中会出现大量的服务,每个服务都要有自己都一些配置信息,或者相同的配置信息,可能不同环境每个服务也有单独的一套配置,这种情况配置文件数量比较庞大,维护起来相当费劲,举个栗子: 在开发的过程中,一般数据库是开发环境数据库,所有服务DB的IP配置为:92.168.0.1,突然老大说,开发环境换了,DB的IP要修改,这下可不好受了,所有模块挨个修改DB的配置,就问你难受不难受?

spring cloud互联网分布式微服务云平台规划分析--spring cloud服务统一配置中心

1.介绍鸿鹄云架构[服务统一配置中心]为分布式系统中的外部配置提供服务器和客户端支持.使用commonservice-config,可以在所有环境中管理应用程序的外部属性.应用程序可通过从开发人员到测试和生产的部署流程,可以管理这些环境之间的配置,并确定应用程序具有迁移时需要运行的一切.服务器存储后端的默认实现使用git,因此它轻松支持标签版本的配置环境,以及可以访问用于管理内容的各种工具.很容易添加替代实现,并使用Spring Cloud Bus配置刷新方案.更多资源欢迎球911708498