面试题答案
一键面试架构设计思路
- 服务发现:通过
ServiceDiscovery
接口,服务实例在启动时向注册中心注册自己的信息,其他服务通过该接口从注册中心获取可用服务实例列表。 - 负载均衡:
LoadBalancer
接口负责从ServiceDiscovery
获取的服务实例列表中,根据一定算法(如随机、轮询等)选择一个合适的实例来处理请求,实现负载均衡。 - 熔断机制:
CircuitBreaker
接口监控服务调用的健康状态,当失败次数达到一定阈值时,触发熔断,不再向故障服务发送请求,避免大量无效请求堆积。同时,在熔断一段时间后尝试半开状态,逐步恢复对服务的调用。
关键接口和结构体代码示例
// ServiceDiscovery接口定义服务发现功能
type ServiceDiscovery interface {
Register(serviceName, instanceAddr string) error
Discover(serviceName string) ([]string, error)
}
// LoadBalancer接口定义负载均衡功能
type LoadBalancer interface {
SelectInstance(serviceInstances []string) string
}
// CircuitBreaker接口定义熔断机制
type CircuitBreaker interface {
Execute(f func() (interface{}, error)) (interface{}, error)
}
// 简单的服务发现结构体实现
type SimpleServiceDiscovery struct {
serviceInstances map[string][]string
}
func (s *SimpleServiceDiscovery) Register(serviceName, instanceAddr string) error {
if s.serviceInstances == nil {
s.serviceInstances = make(map[string][]string)
}
s.serviceInstances[serviceName] = append(s.serviceInstances[serviceName], instanceAddr)
return nil
}
func (s *SimpleServiceDiscovery) Discover(serviceName string) ([]string, error) {
instances, ok := s.serviceInstances[serviceName]
if!ok {
return nil, fmt.Errorf("service %s not found", serviceName)
}
return instances, nil
}
// 简单的负载均衡结构体实现(随机选择)
type RandomLoadBalancer struct{}
func (r *RandomLoadBalancer) SelectInstance(serviceInstances []string) string {
if len(serviceInstances) == 0 {
return ""
}
index := rand.Intn(len(serviceInstances))
return serviceInstances[index]
}
// 简单的熔断机制结构体实现
type SimpleCircuitBreaker struct {
failureThreshold int
successThreshold int
state string
failureCount int
successCount int
}
func NewSimpleCircuitBreaker(failureThreshold, successThreshold int) *SimpleCircuitBreaker {
return &SimpleCircuitBreaker{
failureThreshold: failureThreshold,
successThreshold: successThreshold,
state: "closed",
}
}
func (c *SimpleCircuitBreaker) Execute(f func() (interface{}, error)) (interface{}, error) {
if c.state == "open" {
return nil, fmt.Errorf("service is in open state, cannot execute")
}
result, err := f()
if err != nil {
c.failureCount++
if c.failureCount >= c.failureThreshold {
c.state = "open"
}
return nil, err
}
c.successCount++
if c.successCount >= c.successThreshold {
c.state = "closed"
c.failureCount = 0
c.successCount = 0
}
return result, nil
}
组件组合实现高可用、可扩展的微服务系统
func main() {
// 初始化服务发现
serviceDiscovery := &SimpleServiceDiscovery{}
serviceDiscovery.Register("user-service", "127.0.0.1:8080")
serviceDiscovery.Register("user-service", "127.0.0.1:8081")
// 初始化负载均衡
loadBalancer := &RandomLoadBalancer{}
// 初始化熔断机制
circuitBreaker := NewSimpleCircuitBreaker(5, 3)
// 模拟服务调用
callService := func() (interface{}, error) {
instances, err := serviceDiscovery.Discover("user-service")
if err != nil {
return nil, err
}
instance := loadBalancer.SelectInstance(instances)
// 这里实际应该是调用具体服务实例的逻辑,这里简单模拟成功或失败
if rand.Intn(2) == 0 {
return fmt.Sprintf("Successfully called %s", instance), nil
}
return nil, fmt.Errorf("Failed to call %s", instance)
}
// 通过熔断机制执行服务调用
result, err := circuitBreaker.Execute(callService)
if err != nil {
fmt.Println("Call service failed:", err)
} else {
fmt.Println("Call service result:", result)
}
}
在实际应用中,服务发现可以使用如Consul、Etcd等工具;负载均衡可采用更复杂高效的算法;熔断机制可以进一步优化,如增加时间窗口等功能,以构建更健壮、高可用、可扩展的微服务系统。