Skip to content

配置中心

配置中心是微服务架构中用于集中管理和动态更新配置的组件,它解决了配置分散、难以管理、更新困难等问题。

📋 学习目标

完成本教程后,你将能够:

  • 理解配置中心的概念和优势
  • 使用 Apollo 进行配置管理
  • 使用 Nacos 进行配置管理
  • 实现配置的动态更新
  • 实现配置的版本管理
  • 实现配置的权限控制

🎯 配置中心简介

什么是配置中心

配置中心是微服务架构中的配置管理服务,提供:

  • 集中管理:所有配置集中存储和管理
  • 动态更新:配置变更实时生效,无需重启服务
  • 版本控制:配置变更历史记录和回滚
  • 环境隔离:开发、测试、生产环境配置隔离
  • 权限控制:配置访问权限管理

为什么需要配置中心

传统配置管理的问题

  1. 配置分散:配置分散在各个服务中
  2. 难以管理:修改配置需要重启服务
  3. 环境差异:不同环境配置不一致
  4. 配置泄露:敏感配置可能泄露
  5. 更新困难:配置变更需要重新部署

配置中心的优势

  1. 集中管理:统一管理所有配置
  2. 动态更新:配置变更实时生效
  3. 环境隔离:不同环境配置隔离
  4. 安全控制:配置加密和权限控制
  5. 版本管理:配置变更历史追踪

配置中心架构

应用服务 → 配置中心客户端 → 配置中心服务端 → 配置存储
    ↓              ↓                ↓
读取配置      拉取/推送配置      管理配置
    ↓              ↓                ↓
监听变更      接收变更通知      通知客户端

🔧 Apollo 配置中心

什么是 Apollo

Apollo 是携程开源的配置中心,支持:

  • 配置的增删改查
  • 配置的版本管理
  • 配置的灰度发布
  • 配置的实时推送
  • 多环境支持

安装 Apollo

使用 Docker 运行 Apollo:

bash
# 下载 Apollo 快速启动脚本
wget https://github.com/apolloconfig/apollo-quick-start/archive/master.zip
unzip master.zip
cd apollo-quick-start-master

# 启动 Apollo
./demo.sh start

访问 Apollo Portal:http://localhost:8070

默认账号:apollo / admin

Go 客户端集成

1. 安装依赖

bash
go get github.com/apolloconfig/agollo/v4

2. 基础使用

go
package main

import (
	"context"
	"fmt"
	"log"
	"time"

	"github.com/apolloconfig/agollo/v4"
	"github.com/apolloconfig/agollo/v4/env/config"
)

func main() {
	// 配置 Apollo 客户端
	appConfig := &config.AppConfig{
		AppID:          "your-app-id",
		Cluster:        "default",
		NamespaceName:  "application",
		IP:             "http://localhost:8080",
		IsBackupConfig: true,
	}

	// 创建客户端
	client, err := agollo.StartWithConfig(func() (*config.AppConfig, error) {
		return appConfig, nil
	})
	if err != nil {
		log.Fatalf("启动 Apollo 客户端失败: %v", err)
	}

	// 获取配置
	value := client.GetStringValue("key", "default-value")
	fmt.Printf("配置值: %s\n", value)

	// 监听配置变更
	client.AddChangeListener(&CustomChangeListener{})

	// 保持运行
	select {}
}

// CustomChangeListener 自定义变更监听器
type CustomChangeListener struct{}

func (l *CustomChangeListener) OnChange(event *agollo.ChangeEvent) {
	for key, change := range event.Changes {
		fmt.Printf("配置变更: %s, 旧值: %s, 新值: %s\n",
			key, change.OldValue, change.NewValue)
	}
}

func (l *CustomChangeListener) OnNewestChange(event *agollo.FullChangeEvent) {
	fmt.Printf("配置全量更新: %+v\n", event)
}

3. 多命名空间

go
appConfig := &config.AppConfig{
	AppID:          "your-app-id",
	Cluster:        "default",
	NamespaceName:  "application,datasource,redis", // 多个命名空间
	IP:             "http://localhost:8080",
	IsBackupConfig: true,
}

4. 配置类型

go
// 字符串配置
value := client.GetStringValue("key", "default")

// 整数配置
intValue := client.GetIntValue("int-key", 0)

// 布尔配置
boolValue := client.GetBoolValue("bool-key", false)

// JSON 配置
jsonValue := client.GetStringValue("json-key", "{}")

🔧 Nacos 配置中心

什么是 Nacos

Nacos 是阿里巴巴开源的配置中心和服务发现组件,支持:

  • 配置管理
  • 服务发现
  • 动态 DNS
  • 服务健康检查

安装 Nacos

使用 Docker 运行 Nacos:

bash
docker run -d \
  --name nacos \
  -e MODE=standalone \
  -p 8848:8848 \
  -p 9848:9848 \
  nacos/nacos-server:v2.2.0

访问 Nacos Console:http://localhost:8848/nacos

默认账号:nacos / nacos

Go 客户端集成

1. 安装依赖

bash
go get github.com/nacos-group/nacos-sdk-go/v2

2. 基础使用

go
package main

import (
	"fmt"
	"log"
	"time"

	"github.com/nacos-group/nacos-sdk-go/v2/clients"
	"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
	"github.com/nacos-group/nacos-sdk-go/v2/vo"
)

func main() {
	// 配置 Nacos 客户端
	sc := []constant.ServerConfig{
		{
			IpAddr: "localhost",
			Port:   8848,
		},
	}

	cc := constant.ClientConfig{
		NamespaceId:         "public",
		TimeoutMs:           5000,
		NotLoadCacheAtStart: true,
		LogDir:              "/tmp/nacos/log",
		CacheDir:            "/tmp/nacos/cache",
		LogLevel:            "debug",
	}

	// 创建配置客户端
	configClient, err := clients.CreateConfigClient(map[string]interface{}{
		"serverConfigs": sc,
		"clientConfig":  cc,
	})
	if err != nil {
		log.Fatalf("创建配置客户端失败: %v", err)
	}

	// 获取配置
	content, err := configClient.GetConfig(vo.ConfigParam{
		DataId: "example",
		Group:  "DEFAULT_GROUP",
	})
	if err != nil {
		log.Fatalf("获取配置失败: %v", err)
	}
	fmt.Printf("配置内容: %s\n", content)

	// 监听配置变更
	err = configClient.ListenConfig(vo.ConfigParam{
		DataId: "example",
		Group:  "DEFAULT_GROUP",
		OnChange: func(namespace, group, dataId, data string) {
			fmt.Printf("配置变更: namespace=%s, group=%s, dataId=%s, data=%s\n",
				namespace, group, dataId, data)
		},
	})
	if err != nil {
		log.Fatalf("监听配置失败: %v", err)
	}

	// 保持运行
	select {}
}

3. 发布配置

go
// 发布配置
success, err := configClient.PublishConfig(vo.ConfigParam{
	DataId:  "example",
	Group:   "DEFAULT_GROUP",
	Content: "key=value\nkey2=value2",
})
if err != nil {
	log.Fatalf("发布配置失败: %v", err)
}
fmt.Printf("发布配置成功: %v\n", success)

4. 删除配置

go
// 删除配置
success, err := configClient.DeleteConfig(vo.ConfigParam{
	DataId: "example",
	Group:  "DEFAULT_GROUP",
})
if err != nil {
	log.Fatalf("删除配置失败: %v", err)
}
fmt.Printf("删除配置成功: %v\n", success)

🎯 实践示例

示例:使用配置中心管理数据库配置

go
package main

import (
	"context"
	"fmt"
	"log"

	"github.com/apolloconfig/agollo/v4"
	"github.com/apolloconfig/agollo/v4/env/config"
)

type DatabaseConfig struct {
	Host     string
	Port     int
	Username string
	Password string
	Database string
}

func loadDatabaseConfig(client *agollo.Client) (*DatabaseConfig, error) {
	config := &DatabaseConfig{
		Host:     client.GetStringValue("db.host", "localhost"),
		Port:     client.GetIntValue("db.port", 3306),
		Username: client.GetStringValue("db.username", "root"),
		Password: client.GetStringValue("db.password", ""),
		Database: client.GetStringValue("db.database", "test"),
	}
	return config, nil
}

func main() {
	// 初始化 Apollo 客户端
	appConfig := &config.AppConfig{
		AppID:          "my-app",
		Cluster:        "default",
		NamespaceName:  "application",
		IP:             "http://localhost:8080",
		IsBackupConfig: true,
	}

	client, err := agollo.StartWithConfig(func() (*config.AppConfig, error) {
		return appConfig, nil
	})
	if err != nil {
		log.Fatalf("启动 Apollo 客户端失败: %v", err)
	}

	// 加载数据库配置
	dbConfig, err := loadDatabaseConfig(client)
	if err != nil {
		log.Fatalf("加载数据库配置失败: %v", err)
	}
	fmt.Printf("数据库配置: %+v\n", dbConfig)

	// 监听配置变更
	client.AddChangeListener(&DatabaseConfigListener{})

	// 保持运行
	select {}
}

type DatabaseConfigListener struct{}

func (l *DatabaseConfigListener) OnChange(event *agollo.ChangeEvent) {
	for key, change := range event.Changes {
		if key == "db.host" || key == "db.port" || key == "db.username" ||
			key == "db.password" || key == "db.database" {
			fmt.Printf("数据库配置变更: %s, 旧值: %s, 新值: %s\n",
				key, change.OldValue, change.NewValue)
			// 重新连接数据库
		}
	}
}

func (l *DatabaseConfigListener) OnNewestChange(event *agollo.FullChangeEvent) {
	fmt.Printf("数据库配置全量更新\n")
}

💡 最佳实践

1. 配置命名规范

应用配置: application
数据源配置: datasource
Redis 配置: redis
消息队列配置: mq
第三方服务配置: third-party

2. 配置分组

  • 按环境分组:dev、test、prod
  • 按功能分组:database、cache、mq
  • 按服务分组:user-service、order-service

3. 敏感配置加密

go
// 加密敏感配置
encryptedPassword := encrypt(client.GetStringValue("db.password", ""))

4. 配置默认值

go
// 总是提供默认值
value := client.GetStringValue("key", "default-value")

5. 配置变更处理

go
// 监听配置变更并重新初始化
client.AddChangeListener(&ConfigChangeListener{
	OnChange: func(key string, oldValue, newValue string) {
		if key == "db.host" {
			// 重新连接数据库
			reconnectDatabase(newValue)
		}
	},
})

🚀 总结

配置中心是微服务架构中重要的基础设施,它提供了:

  1. 集中管理:统一管理所有配置
  2. 动态更新:配置变更实时生效
  3. 环境隔离:不同环境配置隔离
  4. 版本控制:配置变更历史追踪
  5. 权限控制:配置访问权限管理

通过 Apollo 或 Nacos,我们可以轻松实现配置的集中管理和动态更新。

📚 扩展阅读

💻 代码示例

完整的代码示例请参考:

示例包括:

  • Apollo 基础使用
  • Apollo 数据库配置
  • Nacos 基础使用
  • Nacos 配置发布

⏭️ 下一步


🎉 恭喜! 你已经掌握了配置中心的基础知识。继续学习下一个主题,构建更强大的微服务系统!

基于 VitePress 构建