前言
"鞠躬尽瘁,死而后已。" —— 诸葛亮
作为一名硬件产品经理,我在管理硬件项目的同时,也需要搭建配套的后端服务。Kongming(孔明)是我基于Go语言开发的微服务框架,命名源自三国时期的智慧化身诸葛亮。本文将分享Kongming的设计理念与架构实现。
为什么需要Kongming?
传统单体架构的痛点
在开发XingJu(星聚)这样的跨平台应用时,我遇到了以下问题:
| 问题 | 影响 |
|---|---|
| 代码耦合严重 | 一个模块的改动影响全局 |
| 部署困难 | 每次发布都是全量更新 |
| 扩展受限 | 无法针对热点服务单独扩容 |
| 技术栈固化 | 难以引入新技术 |
微服务的优势
- 独立部署:每个服务可以独立开发、测试、部署
- 技术异构:不同服务可以选择最适合的技术栈
- 弹性伸缩:根据负载动态调整服务实例
- 故障隔离:单个服务故障不会影响整体系统
Kongming架构设计
命名哲学
Kongming的模块命名借鉴三国文化,体现东方智慧与现代架构的结合:
``
Kongming(孔明)- 框架核心
├── 八卦 Bagua - 服务治理中心
├── 主公 Lord - 配置管理中心
├── 武将 Generals - 服务实例管理
├── 虎符 TigerSeal - 认证授权中心
└── 信使 Courier - 消息队列系统
`
核心架构图
`
┌─────────────────────────────────────────────────────────────┐
│ API Gateway │
│ (Nginx/Kong) │
└───────────────────────┬─────────────────────────────────────┘
│
┌───────────────┼───────────────┐
│ │ │
┌────▼────┐ ┌────▼────┐ ┌────▼────┐
│ Service │ │ Service │ │ Service │
│ A │ │ B │ │ C │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
└───────────────┼───────────────┘
│
┌───────────────┼───────────────┐
│ │ │
┌────▼────┐ ┌────▼────┐ ┌────▼────┐
│ Bagua │ │ Lord │ │ Courier │
│服务治理 │ │配置中心 │ │消息队列 │
└─────────┘ └─────────┘ └─────────┘
`
核心模块详解
1. 八卦 Bagua - 服务治理中心
`go
package bagua
// ServiceRegistry 服务注册中心
type ServiceRegistry struct {
services map[string]*ServiceInstance
mu sync.RWMutex
}
// ServiceInstance 服务实例
type ServiceInstance struct {
ID string
Name string
Address string
Port int
Weight int
Healthy bool
Metadata map[string]string
}
// Register 服务注册
func (r ServiceRegistry) Register(instance ServiceInstance) error {
r.mu.Lock()
defer r.mu.Unlock()
key := fmt.Sprintf("%s:%s", instance.Name, instance.ID)
r.services[key] = instance
log.Printf("服务注册成功: %s@%s:%d", instance.Name, instance.Address, instance.Port)
return nil
}
// Discover 服务发现
func (r ServiceRegistry) Discover(serviceName string) ([]ServiceInstance, error) {
r.mu.RLock()
defer r.mu.RUnlock()
var instances []*ServiceInstance
for key, instance := range r.services {
if strings.HasPrefix(key, serviceName+":") && instance.Healthy {
instances = append(instances, instance)
}
}
return instances, nil
}
`
2. 主公 Lord - 配置管理中心
`go
package lord
// ConfigCenter 配置中心
type ConfigCenter struct {
provider ConfigProvider
cache map[string]interface{}
watchers map[string][]ConfigWatcher
}
// ConfigProvider 配置提供者接口
type ConfigProvider interface {
Get(key string) (string, error)
Set(key string, value string) error
Watch(key string, callback ConfigWatcher) error
}
// LoadConfig 加载配置
func (cc ConfigCenter) LoadConfig(appName string, env string) (AppConfig, error) {
config := &AppConfig{
AppName: appName,
Env: env,
}
// 从etcd/consul加载配置
dbConfigKey := fmt.Sprintf("/config/%s/%s/database", appName, env)
dbConfig, err := cc.provider.Get(dbConfigKey)
if err != nil {
return nil, err
}
if err := json.Unmarshal([]byte(dbConfig), &config.Database); err != nil {
return nil, err
}
return config, nil
}
// HotReload 热更新配置
func (cc *ConfigCenter) HotReload(key string, newValue string) error {
cc.mu.Lock()
defer cc.mu.Unlock()
// 更新缓存
cc.cache[key] = newValue
// 通知所有观察者
if watchers, ok := cc.watchers[key]; ok {
for _, watcher := range watchers {
go watcher.OnConfigChange(key, newValue)
}
}
return nil
}
`
3. 信使 Courier - 消息队列系统
`go
package courier
// MessageQueue 消息队列接口
type MessageQueue interface {
Publish(topic string, message *Message) error
Subscribe(topic string, handler MessageHandler) error
Unsubscribe(topic string, handler MessageHandler) error
}
// Courier 消息总线
type Courier struct {
broker MessageBroker
topics map[string][]MessageHandler
mu sync.RWMutex
}
// Publish 发布消息
func (c *Courier) Publish(topic string, payload interface{}) error {
message := &Message{
ID: uuid.New().String(),
Topic: topic,
Payload: payload,
Timestamp: time.Now(),
}
return c.broker.Publish(topic, message)
}
// Subscribe 订阅消息
func (c *Courier) Subscribe(topic string, handler MessageHandler) error {
c.mu.Lock()
defer c.mu.Unlock()
c.topics[topic] = append(c.topics[topic], handler)
return c.broker.Subscribe(topic, handler)
}
`
服务间通信
gRPC + Protocol Buffers
`protobuf
syntax = "proto3";
package kongming;
service UserService {
rpc GetUser(GetUserRequest) returns (GetUserResponse);
rpc CreateUser(CreateUserRequest) returns (CreateUserResponse);
rpc UpdateUser(UpdateUserRequest) returns (UpdateUserResponse);
rpc DeleteUser(DeleteUserRequest) returns (DeleteUserResponse);
}
message GetUserRequest {
string user_id = 1;
}
message GetUserResponse {
User user = 1;
Error error = 2;
}
message User {
string id = 1;
string username = 2;
string email = 3;
int64 created_at = 4;
}
`
实战案例:XingJu后端服务
服务拆分
`
xingju-backend/
├── api-gateway/ # API网关
├── user-service/ # 用户服务
├── search-service/ # 搜索服务
├── content-service/ # 内容服务
├── notification-service/ # 通知服务
└── kongming/ # 基础设施
`
服务注册与发现
`go
func main() {
// 初始化Kongming
km := kongming.New(
kongming.WithEtcdEndpoints([]string{"localhost:2379"}),
kongming.WithServiceName("search-service"),
kongming.WithPort(8080),
)
// 注册服务
if err := km.Register(); err != nil {
log.Fatal(err)
}
// 启动gRPC服务
server := grpc.NewServer()
pb.RegisterSearchServiceServer(server, &SearchServiceImpl{})
// 优雅关闭
km.Shutdown(func() {
server.GracefulStop()
})
}
`
性能优化
1. 负载均衡
`go
// WeightedRoundRobin 加权轮询
type WeightedRoundRobin struct {
instances []*ServiceInstance
weights []int
current int
}
func (wrr WeightedRoundRobin) Next() ServiceInstance {
if len(wrr.instances) == 0 {
return nil
}
instance := wrr.instances[wrr.current]
wrr.current = (wrr.current + 1) % len(wrr.instances)
return instance
}
`
2. 熔断器
`go
// CircuitBreaker 熔断器
type CircuitBreaker struct {
failureThreshold int
successThreshold int
timeout time.Duration
failures int
successes int
lastFailure time.Time
state State
}
type State int
const (
StateClosed State = iota // 关闭 - 正常
StateOpen // 开启 - 熔断
StateHalfOpen // 半开 - 试探
)
func (cb *CircuitBreaker) Call(fn func() error) error {
if cb.state == StateOpen {
if time.Since(cb.lastFailure) < cb.timeout {
return ErrCircuitOpen
}
cb.state = StateHalfOpen
}
err := fn()
if err != nil {
cb.recordFailure()
return err
}
cb.recordSuccess()
return nil
}
`
监控与告警
Prometheus + Grafana
`go
package observatory
var (
RequestDuration = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "kongming_request_duration_seconds",
Help: "Request duration in seconds",
Buckets: prometheus.DefBuckets,
},
[]string{"service", "method"},
)
RequestCount = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "kongming_request_total",
Help: "Total number of requests",
},
[]string{"service", "method", "status"},
)
)
func init() {
prometheus.MustRegister(RequestDuration)
prometheus.MustRegister(RequestCount)
}
``
总结
Kongming框架的设计理念:
- 简洁优雅:Go语言的简洁哲学贯穿始终
- 东方智慧:三国文化命名,易于理解和记忆
- 生产就绪:包含服务治理、监控、告警等完整功能
- 易于扩展:模块化设计,方便二次开发
下一步计划
- [ ] 支持Kubernetes原生部署
- [ ] 集成Istio服务网格
- [ ] 完善分布式链路追踪
- [ ] 开源发布v1.0版本
相关项目
最后更新:2026年4月3日