go-micro@v4.9.0源码阅读
- 一、前言
- 二、创建微服务
- 三、源码阅读
- 操作一:注册服务处理
- 操作二:组件配置
- 操作三:启动微服务
- Step 1 :启动微服务
- Step 2 :开启服务关闭监听
- Step 3 :停⽌Server组件
- Step 4 :停⽌Profile组件
一、前言
Go是一款开源的编程语言,能更容易地构造简单、可靠且高效的软件,具备高并发,静态编译等特性,在性能、安全等方面具备非常大的优势。
而go-micro则是基于Go的微服务编程框架,操作简单、编码高效、功能强大。想进一步了解go-micro,请查看我们的往期文章:go-micro学习与实践
本文章基于基于go-micro@v4.9.0版本,内容全面详实,预计阅读时长10分钟,建议先收藏! 那么下面就让我们开启go-micro源码阅读之旅吧!
二、创建微服务
使⽤官⽹提供的cli插件直接创建⼀个微服务。
插件下载:go install github.com/go-micro/cli/cmd/go-micro@latest
创建微服务 :go-micro new service helloworld
依赖更新及下载 :make init proto update tidy
微服务创建成功后,微服务包含以下⼏个⽬录结构:
三、源码阅读
下面我们先从微服务的启动入口 main.go 开始分析起。
main.go
func main() {
// 组件配置
srv := micro.NewService(
//micro.Name(service),
//micro.Version(version),
micro.Server(server.DefaultServer),
micro.Client(client.DefaultClient),
micro.Broker(broker.DefaultBroker),
micro.Registry(registry.DefaultRegistry),
micro.Transport(transport.DefaultTransport),
micro.Auth(auth.DefaultAuth),
micro.Cache(cache.DefaultCache),
micro.Cmd(cmd.DefaultCmd),
micro.Config(config.DefaultConfig),
micro.Runtime(runtime.DefaultRuntime),main进⾏了三个操作:组件配置,注册服务处理,启动微服务
注册服务处理
proto:定义服务
helloworld.proto:protobuf格式的协议定义服务
上述定义了⼀个服务Helloworld,该服务包含4个⽅法:Call, ClientStream, ServerStream, BidiStream
helloworld.pb.go:由protoc --go_out=:. proto/helloworld.proto⽣成。该⽂件会包含⽅法⼊参,出参的结构体及
对应的编码规范。
helloworld.pb.micro.go:由protoc --micro_out=. proto/hellloworld.proto⽣成。该⽂件会包含
HelloworldHandler接⼝(该接⼝包含了4个服务⽅法),及该接⼝注册到微服务的RegisterHelloworldHandler。
handler:微服务的具体处理逻辑
helloworld.go:实现helloworld.pb.micro.go中定义的HelloworldHandler接⼝。
注册流程,详⻅核⼼组件server.Server组件讲解;调⽤流程,详⻅client.Client组件讲解。
组件配置
micro.Profile(profile.DefaultProfile),
micro.Store(store.DefaultStore),
micro.Logger(logger.DefaultLogger),
)
srv.Init()
// 注册服务处理
pb.RegisterHelloworldHandler(srv.Server(), new(handler.Helloworld))
// 启动微服务
if err := srv.Run(); err != nil {
log.Fatal(err)
}
}
可以看到,main进⾏了三个操作:
注册服务处理
组件配置
启动微服务
下面我们逐个来看这三个操作。
操作一:注册服务处理
1.1 proto:定义服务
helloworld.proto: protobuf格式的协议定义服务
service Helloworld {
rpc Call(CallRequest) returns (CallResponse) {}
rpc ClientStream(stream ClientStreamRequest) returns (ClientStreamResponse) {}
rpc ServerStream(ServerStreamRequest) returns (stream ServerStreamResponse) {}
rpc BidiStream(stream BidiStreamRequest) returns (stream BidiStreamResponse) {}
}
上述定义了⼀个服务Helloworld,该服务包含4个⽅法:Call, ClientStream, ServerStream, BidiStream。
helloworld.pb.go
由protoc --go_out=:. proto/helloworld.proto⽣成。该⽂件会包含⽅法⼊参,出参的结构体及对应的编码规范。
helloworld.pb.micro.go
由protoc --micro_out=. proto/hellloworld.proto⽣成。
该⽂件会包含HelloworldHandler接⼝(该接⼝包含了4个服务⽅法),及该接⼝注册到微服务的RegisterHelloworldHandler。
1.2 handler:微服务的具体处理逻辑
helloworld.go
实现helloworld.pb.micro.go中定义的HelloworldHandler接⼝。
注册流程,详⻅核⼼组件server.Server组件讲解;调⽤流程,详⻅client.Client组件讲解。
操作二:组件配置
2.1 顶层结构
micro.Service
微服务的顶层抽象。⽤于定义微服务的服务信息及控制着整个微服务⽣命周期。包含以下⼏个⽅法。
type Service interface {
// The service name
Name() string
// Init initialises options
Init(...Option)
// Options returns the current options
Options() Options
// Client is used to call services
Client() client.Client
// Server is for handling requests and events
Server() server.Server
// Run the service
Run() error
// The service implementation
String() string
}
默认实现的结构体为micro.service
type service struct {
opts Options
once sync.Once
}
opts Options 是微服务的配置项,包含该微服务⽤到的其他组件,⽣命周期执⾏钩⼦函数(服务启动前执⾏钩⼦函数,服务关闭前执⾏的钩⼦函数,服务启动后执⾏的钩⼦函数,服务关闭后执⾏的钩⼦函数),服务上下⽂,是否启⽤系统信号关闭服务的配置项。
once sync.Once 保证只执⾏⼀次加载启动参数。
2.2 核心组件
核⼼组件是构成微服务的必要组件。
server.Server:微服务的服务端
type Server interface {
// Initialise options
Init(...Option) error
// Retrieve the options
Options() Options
// Register a handler
Handle(Handler) error
// Create a new handler
NewHandler(interface{}, ...HandlerOption) Handler
// Create a new subscriber
NewSubscriber(string, interface{}, ...SubscriberOption) Subscriber
// Register a subscriber
Subscribe(Subscriber) error
// Start the server
Start() error
// Stop the server
Stop() error
// Server implementation
String() string
}
以mucp的实现为例。实现组件的结构体为server.rpcServer
type rpcServer struct {
router *router
exit chan chan error
sync.RWMutex
opts Options
handlers map[string]Handler
subscribers map[Subscriber][]broker.Subscriber
// marks the serve as started
started bool
// used for first registration
registered bool
// subscribe to service name
subscriber broker.Subscriber
// graceful exit
wg *sync.WaitGroup
rsvc *registry.Service
}
rpcServer 包含以下⼏种信息:
#1 服务处理
rpcServer有两种服务处理:
⼀种是表示服务请求的rpcHandler
⼀种是表示消息处理的subscriber
rpcHandler:⼀个微服务可定义多个rpc服务,每个rpc服务对应⼀个的rpcHandler,通过map的形式保存在rpcServer中。
通过NewHandler⽅法⽣成, handler为⼀个⾃定义的结构体,该结构体对应rpc服务名,结构体上的外部⽅法对应rpc服务⽅法。
subscriber:⼀个微服务可订阅多个消息,每个消息对应⼀个subscriber,通过map的形式保存在rpcServer中。
通过NewSubscriber⽅法⽣成,参数topic表示订阅的消息;参数sub是⼀个⽅法,⽅法签名为:
“func(context.Context, interface{}) error”
表示该消息的处理逻辑。
#2 路由
构建路由信息
绑定服务:⽤户将服务注册到框架中。rpcServer针对两种请求类型有不同的绑定⽅法。
解析服务:解析路由信息,解析服务处理信息存储到router中。
服务注册:将服务信息,节点信息,路由信息,发送到服务注册中⼼进⾏注册。
使⽤路由信息
接收消息:从注册中⼼或消息中⼼,接收到需要处理的请求。
统⼀拦截:接受到请求后,执⾏中间件中的函数,先配置的先执⾏。
端点分发:根据请求端点,匹配到分发器中的对应处理⽅法的放射类型。
请求解码:根据content-type,对请求体进⾏解码,得到⽅法的⼊参。
服务处理:使⽤⼊参,执⾏反射⽅法。
rpcServer的router路由中存储着两种不同类型的路由。
#3 配置
rpcServer包含多种配置信息:
节点信息配置:包含服务id,服务名称,监听地址,节点元数据,上下⽂等。
组件配置:包含注册中⼼,消息中⼼,服务通信,编码器等
拦截器配置:包含服务请求拦截器,消息通知拦截器。
#4 状态信息
rpcServer的状态信息包含:服务运⾏状态,注册状态,退出执⾏状态等。
client.Client:微服务的客户端
type Client interface {
Init(...Option) error
Options() Options
NewMessage(topic string, msg interface{}, opts ...MessageOption) Message // 构建消息
NewRequest(service, endpoint string, req interface{}, reqOpts ...RequestOption)
Request // 构建服务请求
Call(ctx context.Context, req Request, rsp interface{}, opts ...CallOption) error //
调⽤服务端
Stream(ctx context.Context, req Request, opts ...CallOption) (Stream, error) // 构建
双向通信
Publish(ctx context.Context, msg Message, opts ...PublishOption) error // 发布消息
String() string
}
以mucp的实现为例。实现组件的结构体为client.rpcClient
type rpcClient struct {
seq uint64
once atomic.Value
opts Options
pool pool.Pool
}
rpcClient 包含以下⼏种信息:
#1 请求链
构建请求: rpcClient针对两种不同的请求类型,有不同构建⽅法。
请求备份:发起请求后,通过BackoffFunc函数对请求进⾏备份,备份时,会阻塞请求。rpcClient没有默认的请求备份,⽀持⾃定义配置BackoffFunc函数。
选择节点:从注册中⼼获取请求⽬标服务对应的所有节点。通过Selector选择器选取节点, rpcClient默认使⽤随机算法来选取节点,⽀持⾃定义选择器。
中间件:选取节点后,执⾏中间件函数。先配置的先执⾏。
发送请求:
- 选择好的服务节点建⽴连接,连接建⽴成功后,将连接放⼊连接池,请求重试时,后续相同的请求可以直接在连接池中获取
- 使⽤编码器对请求编码,发送请求数据
解析响应:获取响应后,使⽤解码器对响应解码并依次返回到最上层⽅法。
#2 配置
组件配置:消息中⼼,编码/解码器,注册中⼼,节点选择器,通信⽅式等。
请求配置:连接池,中间件,超时时间等。
2.2 核心组件衍生
broker.Broker
消息组件,⽤于与消息中⼼交互。
type Broker interface {
Init(...Option) error
Options() Options
Address() string
Connect() error
Disconnect() error
Publish(topic string, m *Message, opts ...PublishOption) error
Subscribe(topic string, h Handler, opts ...SubscribeOption) (Subscriber, error)
String() string
}
以http实现为例。 http是go-micro默认组件实现,具体的结构体为broker.HttpBroker
type httpBroker struct {
id string
address string
opts Options
mux *http.ServeMux
c *http.Client
r registry.Registry
sync.RWMutex
subscribers map[string][]*httpSubscriber
running bool
exit chan chan error
// offline message inbox
mtx sync.RWMutex
inbox map[string][][]byte
}
httpBroker 包含以下⼏种信息:
#1 发布消息
httpBroker通过Publish⽅法发布消息。
消息编码:httpBroker默认使⽤json进⾏消息编码。编码完的消息缓存到inbox字段中。
获取订阅端:每个订阅端节点,都会以微服务的形式将订阅信息注册到服务注册中⼼。不同于其他⾃定义的微服务,订阅端微服务的名称为固定值:micro.http.broker。
(当⼀个节点有订阅消息时,会注册两个微服务信息,⼀个是⾃身service定义的微服务,⼀个是固定的消息订阅微服务)。
httpBroker先通过微服务名(micro.http.broker)获取所有的订阅端节点信息,然后通过topic过滤得到对应消息订阅端的节点列表。
发送http请求:httpBroker通过节点选取规则选择节点,从inbox中取出消息,并向这些节点发送http请求。
httpBroker有两种选取规则。通过broker.Queue()进⾏设置。
#2 订阅消息
httpBroker通过Subscribe⽅法订阅消息:
注册订阅微服务:httpBroker构建微服务信息,并注册到注册中⼼。
微服务信息包含:服务名(固定值:
micro.http.broker),消息topic,处理函数,当前节点信息等。
#3 配置
httpBroker可配置的信息有: broker相关信息(地址, tls连接,上下⽂等), registry相关信息,编码器等
#4 状态信息
httpBroker有两种状态:
⼀种是连接状态,⼀种是断开状态。
registry. Registry
服务注册中⼼组件,⽤于与注册中⼼交互。服务注册中⼼存储所有的服务节点信息,以便于其他节点能够获取。
type Registry interface {
Init(...Option) error
Options() Options
Register(*Service, ...RegisterOption) error
Deregister(*Service, ...DeregisterOption) error
GetService(string, ...GetOption) ([]*Service, error)
ListServices(...ListOption) ([]*Service, error)
Watch(...WatchOption) (Watcher, error)
String() string
}
以etcd实现为例。etcd实现不是go-micro的默认实现,需要引⼊go-micro组件库。etcd实现的结构体为etcd.etcdRegistry。
type etcdRegistry struct {
client *clientv3.Client
options registry.Options
sync.RWMutex
register map[string]uint64
leases map[string]clientv3.LeaseID
}
etcdRegistry 包含以下信息:
#1 注册
etcdRegistry通过etcd的api进⾏注册、续约、删除等操作。
etcdRegistry包含两个注册相关数据:
register map[string]uint64:存储已注册节点的hash值,当该节点再次发起注册时,对⽐节点信息是否有更改。
leases map[string]clientv3.LeaseID:存储已注册节点的LeaseID,当该节点再次发起注册时(注册⼼跳维持场景),进⾏注册续约。
#2 配置
配置信息包含registry连接配置(地址, ttl, tls,上下⽂等), etcd连接客户端。
transport.Transport
微服务调⽤组件。定义服务间通信⽅式。
以http实现为例。transport.httpTransport是go-micro的默认实现。
type httpTransport struct {
opts Options
}
httpTransport 包含以下信息:
#1 监听
端⼝监听:启动tcp端⼝监听。返回监听器httpTransportListener。
建⽴连接:⼀个微服务可订阅多个消息,每个消息对应⼀个subscriber,通过map的形式保存在rpcServer中。
#2 请求
创建连接:创建tcp连接到服务端。返回客户端httpTransportClient。
发送数据:通过Send⽅法,将请求写⼊到连接中。
接收数据:通过Recv⽅法,从连接中读取响应。
#3 配置
配置包含:连接地址, tls, ttl,上下⽂等。
2.3 功能组件
功能组件在核⼼流程中并未使⽤。应根据需要⾃⾏使⽤。
auth.Auth
认证组件
type Auth interface {
// Init the auth
Init(opts ...Option)
// Options set for auth
Options() Options
// Generate a new account
Generate(id string, opts ...GenerateOption) (*Account, error)
// Inspect a token
Inspect(token string) (*Account, error)
// Token generated using refresh token or credentials
Token(opts ...TokenOption) (*Token, error)
// String returns the name of the implementation
String() string
}
以jwt实现为例。go-micro默认没有实现。组件库中jwt实现的结构体为jwt.jwt
type jwt struct {
sync.Mutex
options auth.Options
jwt jwtToken.Provider
}
jwt 包含以下⼏种信息:
#1 token⽣成器
组装账号信息:通过Generate⽅法⽣成账号信息,账号信息包含⽤户id, secret(由jwt⽣成器⽣成,⽤于传递到token解析),⾃定义信息等。
⽣成token:通过账号的secret解析出完整的账号信息(secret时效为15min,超时⽆法头盖⻣secret解析账号信息)。
然后再通过jwt⽣成器,对账号信息进⾏加密,⽣成具有指定时效的accesstoken和refreshtoken(refreshtoken的时效⽐accesstoken的⻓1h)。
解析token:从token值(accesstoken或refreshtoken)中解析出账号信息,超时的⽆法解析。
#2 配置
包含的配置信息有: jwt⽣成器配置(jwt公钥,私钥, token有效时间等),账号信息配置(⾃定义信息等)
cache.Cache
缓存组件
type Cache interface {
// Get gets a cached value by key.
Get(ctx context.Context, key string) (interface{}, time.Time, error)
// Put stores a key-value pair into cache.
Put(ctx context.Context, key string, val interface{}, d time.Duration) error
// Delete removes a key from cache.
Delete(ctx context.Context, key string) error
// String returns the name of the implementation.
String() string
}
以redis实现为例。go-micro的缓存是key-value格式,默认memory实现, redis的实现结构体为redis.redisCache
type redisCache struct {
opts cache.Options
client redis.UniversalClient
}
redisCache 包含以下⼏种信息:
#1 redis客户端
⽤于和redis进⾏交互。
#2 配置
配置信息包含:缓存有效时间,缓存服务器地址,上下⽂等。
cmd.Cmd
命令⾏组件,用于定义参数等
type Cmd interface {
// The cli app within this cmd
App() *cli.App
// Adds options, parses flags and initialise
// exits on error
Init(opts ...Option) error
// Options set within this command
Options() Options
}
go-micro的默认实现为cmd.cmd
type cmd struct {
opts Options
app *cli.App
}
cmd通过urfave/cli实现参数的设置与读取
设置参数:通过设置cli.App的Flags进⾏参数设置。Flags包含参数类型,命令⾏参数名称,环境变量(多个值),参数说明,默认值等。
解析参数:cli.App会将参数写⼊到cli.Context中,然后通过设置cli.App的Action进⾏参数的解析。
config.Config
配置组件,与配置中⼼交互
type Config interface {
// provide the reader.Values interface
reader.Values
// Init the config
Init(opts ...Option) error
// Options in the config
Options() Options
// Stop the config loader/watcher
Close() error
// Load config sources
Load(source ...source.Source) error
// Force a source changeset sync
Sync() error
// Watch a value for changes
Watch(path ...string) (Watcher, error)
}
go-micro的默认实现为config.config
type config struct {
exit chan bool
opts Options
sync.RWMutex
// the current snapshot
snap *loader.Snapshot
// the current values
vals reader.Values
}
命令⾏组件,用于定义参数等
config 包含以下⼏种信息:
#1 获取数据
config通过Load⽅法或Sync⽅法,从数据源获取数据。获取到数据后,⽣成数据快照。
#2 监听数据
连接到数据源后, config每隔1s从数据源同步数据,监控配置中⼼数据是否发⽣变化,当数据变动时,重新⽣成新的快照数据。
#3 ⽣成快照
数据快照由两个部分构成:
配置数据:从配置中⼼读取到的数据
版本:⽣成快照的时间戳,保证缓存的快照都是最新的。
#4 读取数据
go-micro的配置数据会解析为json格式
获取:通过path获取对于值
删除/更新:只能操作本地的内存数据,配置中⼼的数据不会发⽣变化
runtime.Runtime
服务管理组件。可⽤于管理其他微服务
t
ype Runtime interface {
// Init initializes runtime
Init(...Option) error
// Create registers a service
Create(*Service, ...CreateOption) error
// Read returns the service
Read(...ReadOption) ([]*Service, error)
// Update the service in place以kubernetes实现为例。go-micro的默认实现为runtime.runtime,只适⽤于所有服务在同⼀个操作系统中的场
景。组件的kubernetes实现为kubernetes.kubernetes,适⽤于kubernetes环境。
为了区分,以下通过kubernetes表示runtime的组件, k8s表示kubernetes环境
go-micro中的微服务节点对应kubernetes中的pod,可通过Deployment和Service进⾏控制。故对runtime对微服
务的管理,就是对k8s资源的管理。
kubernetes包含以下信息
kubernetes客户端
kubernetes客户端⽤于请求kubernetes的kube-apiserver。管理k8s资源。
监听微服务事件:runtime组件启动后,会监听从微服务传递过来的事件,事件包含:服务创建,服务更新,服务
删除。
传递到kubernetes:调⽤kube-apiserver,操作Deployment和Service资源。
配置信息
Update(*Service, ...UpdateOption) error
// Remove a service
Delete(*Service, ...DeleteOption) error
// Logs returns the logs for a service
Logs(*Service, ...LogsOption) (LogStream, error)
// Start starts the runtime
Start() error
// Stop shuts down the runtime
Stop() error
// String describes runtime
String() string
}
以kubernetes实现为例。 go-micro的默认实现为runtime.runtime,只适⽤于所有服务在同⼀个操作系统中的场景。组件的kubernetes实现为kubernetes.kubernetes,适⽤于kubernetes环境。
为了区分,以下通过kubernetes表示runtime的组件, k8s表示kubernetes环境
type kubernetes struct {
sync.RWMutex
// options configure runtime
options *runtime.Options
// indicates if we're running
running bool
// used to stop the runtime
closed chan bool
// client is kubernetes client
client client.Client
// namespaces which exist
namespaces []client.Namespace
}
go-micro中的微服务节点对应kubernetes中的pod,可通过Deployment和Service进⾏控制。故对runtime对微服务的管理,就是对k8s资源的管理。
jwt 包含以下⼏种信息:
#1 kubernetes客户端
kubernetes客户端⽤于请求kubernetes的kube-apiserver。管理k8s资源。
监听微服务事件:runtime组件启动后,会监听从微服务传递过来的事件。
事件包含:服务创建,服务更新,服务删除
传递到kubernetes:调⽤kube-apiserver,操作Deployment和Service资源。
#2 配置信息
包含的配置信息有:定时任务(组件启动后执⾏,可创建微服务事件), kubernetes信息(镜像名称,资源类型等)
#3 状态信息
微服务运⾏的命名空间
组件的运⾏状态(启动,关闭)
profile.Profile
pprof组件,采集性能数据
type Profile interface {
// Start the profiler
Start() error
// Stop the profiler
Stop() error
// Name of the profiler
String() string
}
以profiler实现为例。 实现结构体为pprof.profiler
type profiler struct {
opts profile.Options
sync.Mutex
running bool
// where the cpu profile is written
cpuFile *os.File
// where the mem profile is written
memFile *os.File
}
profiler 包含以下⼏种信息:
#1 性能分析
profiler使⽤go⾃带的pprof进⾏性能分析。
cpuFile *os.File:cpu性能分析结果⽂件,通过pprof.StartCPUProfile⽅法记录。
memFile *os.File:内存性能分析结果⽂件,通过pprof.WriteHeapProfile⽅法记录。
#2 配置信息
包含的配置信息有: 分析名称(⽣成临时⽂件的名称)
#3 状态信息
状态信息包含:组件的运⾏状态。
store.Store
数据存储组件。与数据中⼼交互, go-micro数据存储组件⽀持key-value格式数据。
type Store interface {
// Init initialises the store. It must perform any required setup on the backing
storage implementation and check that it is ready for use, returning any errors.
Init(...Option) error
// Options allows you to view the current options.
Options() Options
// Read takes a single key name and optional ReadOptions. It returns matching
[]*Record or an error.
Read(key string, opts ...ReadOption) ([]*Record, error)
// Write() writes a record to the store, and returns an error if the record was not
written.
Write(r *Record, opts ...WriteOption) error
// Delete removes the record with the corresponding key from the store.
Delete(key string, opts ...DeleteOption) error
// List returns any keys that match, or an empty list with no error if none matched.
List(opts ...ListOption) ([]string, error)
// Close the store
Close() error
// String returns the name of the implementation.
String() string
}
以redis实现为例。 redis实现的结构体为redis.rkv
type rkv struct {
ctx context.Context
options store.Options
Client redis.UniversalClient
}
rkv 包含以下⼏种信息:
#1 数据中⼼客户端
通过redis客户端与redis进⾏交互,实现数据的增删改查。
#2 配置
包含的配置信息有: 数据中⼼节点配置,数据库,数据表。
logger.Logger
⽇志记录组件
type Logger interface {
// Init initialises options
Init(options ...Option) error
// The Logger options
Options() Options
// Fields set fields to always be logged
Fields(fields map[string]interface{}) Logger
// Log writes a log entry
Log(level Level, v ...interface{})
// Logf writes a formatted log entry
Logf(level Level, format string, v ...interface{})
// String returns the name of logger
String() string
}
go-micro默认⽇志记录实现为logger.defaultLogger
type defaultLogger struct {
sync.RWMutex
opts Options
}
defaultLogger 包含以下⼏种信息:
#1 日志记录
defaultLogger将⽇志记录的当前时间戳,⽇志等级,公共字段(通过Filed⽅法设置),具体信息。通过fmt.Printf函数输出到系统的STDOUT中
#2 配置
包含的配置信息有:⽇志记录等级,公共字段,输出,上下⽂等。
操作三:启动微服务
Step 1 :启动微服务
使⽤micro.Service的Run⽅法启动微服务时,调⽤server.Server的Start⽅法来启动Server组件。
如果profile.Profile已经配置到了micro.Service的Options中,调⽤profile.Profile的Start⽅法来启动Profile组件。
Step 2 :开启服务关闭监听
服务启动完成后,开启服务关闭监听,服务关闭有以下两种⽅式:
信号关闭:系统接收到SIGTERM、 SIGINT、 SIGQUIT或SIGKILL信号时,关闭服务。可通过配置项(Signal)取消该关闭⽅式。
上下⽂关闭:触发了micro.Service中的定义的上下⽂的取消⽅法时,关闭服务。
Step 3 :停⽌Server组件
使⽤server.Server的Stop⽅法,停⽌Server组件。
Step 4 :停⽌Profile组件
使⽤profile.Profile的Stop⽅法,停⽌Profile组件。
下面我们具体来看其中几点。
- 启动Server组件
- 启动Server
使⽤server.Server的Start⽅法启动Server
- 开启服务监听
使⽤transport.Transport的Listen⽅法开启服务监听。
- 开启消息监听
使⽤broker.Broker的Connect⽅法开启消息监听。
- 开启服务注册
先使⽤RegisterCheck定义的⽅法进⾏服务注册检查。检查通过后,再使⽤Register⽅法进⾏服务注册。
- 处理请求线程
处理请求线程,是⽤来接收到服务请求。并进⾏后续处理。
- 服务注册⼼跳保持线程
系统正常运⾏时,开启定时任务。每隔30s使⽤RegisterCheck定义的⽅法进⾏注册检查,检查通过时,直接使⽤Register注册;检查失败时,先使⽤Deregister⽅法取消注册,再使⽤Deregister⽅法重新注册。
使⽤通道监听服务状态,当收到服务关闭时,停⽌定时任务,使⽤Deregister⽅法取消注册。
- 服务注册(Register⽅法)
开始注册后,先从缓存中获取服务信息,由于需要进⾏服务注册⼼跳保持机制,每次注册的服务信息不会发⽣变化,故可以将需要注册的服务信息进⾏缓存。
服务已经进⾏了缓存,直接获取缓存中的服务信息,使⽤registry.Registry的Register⽅法在注册中⼼注册务。
服务未进⾏缓存,先⽣成节点信息。节点信息包含有:服务名称,服务版本,服务监听的端点(服务请求处理端点和消息通知处理端点),节点信息。
使⽤broker.Broker的Subscribe⽅法在消息中⼼订阅消息,消息订阅端是⽤来绑定订阅的消息和对该消息的处理逻辑。
使⽤regisry.Registry的Register⽅法在注册中⼼注册服务。注册失败时会进⾏重试,共3次。
注册成功后,将服务信息进⾏缓存。
- 取消注册(Deregister⽅法)
取消注册时,先⽣成节点的简要信息。
根据节点简要信息,使⽤registry.Registry的Deregister⽅法取消该节点的注册。
调⽤每个订阅端端Unsubscribe⽅法,在消息中⼼取消订阅
清除服务信息的缓存
- 启动Profile组件
使⽤go⾃带的pprof进⾏启动性能分析。
- 停⽌Server组件
使⽤通道通知服务注册⼼跳保持线程服务已关闭,修改服务的启动状态。
- 停⽌Profile组件
停⽌pprof性能分析。
我们致力于用数字技术重构企业价值,助力企业实现数字化转型升级!