![Kubernetes微服务实战](https://wfqqreader-1252317822.image.myqcloud.com/cover/59/32436059/b_32436059.jpg)
3.5.2 服务实现
下一步是将服务接口实现为简单的Go包。此时,每个服务都有其自己的包:
·github.com/the-gigi/delinkcious/pkg/link_manager
·github.com/the-gigi/delinkcious/pkg/user_manager
·github.com/the-gigi/delinkcious/pkg/social_graph_manager
注意,这些都是Go包的名称,而不是URL。
让我们研究一下social_graph_manager包,它将object_model包作为om导入,因为它需要实现om.SocialGraphManager接口。它定义了一个名为SocialGraph-Manager的结构体,该结构体有一个SocialGraphManager类型名为store的字段。因此,store字段的接口等价于示例中社交图谱manager的接口:
![](https://epubservercos.yuewen.com/0B378C/17517093206689306/epubprivate/OEBPS/Images/048-i.jpg?sign=1739523666-Z0sUvw7evn4FqIQW0W6OPxYsnlCzdr7l-0-ff8f15f87be6fe7bae264c0f23af9e1b)
这可能有点令人困惑。这里的想法是通过store字段实现相同的接口,以便顶层manager可以实现一些验证逻辑并将繁重的工作委托给store,你很快就会看到它的实际应用。
此外,store字段是接口这一事实允许我们使用不同的store实现相同接口,这是非常有用的。NewSocialGraphManager()函数接受一个不能为nil的store字段,然后返回具有指定store的SocialGraphManager新实例:
![](https://epubservercos.yuewen.com/0B378C/17517093206689306/epubprivate/OEBPS/Images/048-2-i.jpg?sign=1739523666-sAidLykqyjVNaM37vJWDAXCYFdtcnStz-0-4be0ee4eb8362c42177d7e7d2fae77d0)
SocialGraphManager结构体本身非常简单,它执行一些有效性检查,然后将工作委托给store:
![](https://epubservercos.yuewen.com/0B378C/17517093206689306/epubprivate/OEBPS/Images/048-3-i.jpg?sign=1739523666-0dVJc5wxkHQisVVWcrLViJ9rn4RpTMpZ-0-fd030256dcb9c56b0366d9e49e36e64d)
![](https://epubservercos.yuewen.com/0B378C/17517093206689306/epubprivate/OEBPS/Images/049-i.jpg?sign=1739523666-k1QxxxBWGwfK6MmfJyXJ6pi7aQaneLCE-0-8be5b6ff740a08cfa8f0085bdd3c6f99)
SocialGraphManager是一个非常简单的库。让我们进一步查看服务本身,该服务(https://github.com/the-gigi/delinkcious/tree/master/svc/social_graph_service)位于svc子目录下。
首先从social_graph_service.go文件开始。我们将介绍它的主要部分,其与大多数服务是相似的。该文件位于service包中,它导入了几个重要的包:
![](https://epubservercos.yuewen.com/0B378C/17517093206689306/epubprivate/OEBPS/Images/049-2-i.jpg?sign=1739523666-ONj8KxePvdQEJSPyUXujDl4TepzPPYRG-0-b4668b5cb4f05d2fcf2a74ef68ea2b7d)
Go kit中的http传输包对于使用HTTP传输的服务是必需的,gorilla/mux包提供了一流的路由功能。
social_graph_manager是完成所有繁重工作的服务的实现,log包用于记录日志,而net/http包用于提供HTTP服务。
代码中只有一个名为Run()的函数。首先,它为社交图谱创建了数据存储,然后创建SocialGraphManager本身,并向其传递store字段,因此,social_graph_manager的功能在这个包中实现,并由service负责制定策略并传递数据存储。如果此时出现任何问题,该服务将仅以log.Fatal()调用退出,因为在这个早期阶段程序无法恢复:
![](https://epubservercos.yuewen.com/0B378C/17517093206689306/epubprivate/OEBPS/Images/049-3-i.jpg?sign=1739523666-A6p2fgyZalS7esyFXO4YJmamWEm12Hdo-0-60eba5968d3a0f749be24bdd64546a7a)
下一部分是为每个端点构造处理程序。这是通过为每个端点调用HTTP传输的New-Server()函数来实现的,其中的参数有Endpoint工厂函数(我们将很快查看)、请求解码器函数和响应编码器函数。对于HTTP服务,通常将请求和响应编码为JSON:
![](https://epubservercos.yuewen.com/0B378C/17517093206689306/epubprivate/OEBPS/Images/050-i.jpg?sign=1739523666-NDW0q1xTed98wnamNRPCKQZuYNvuSTY5-0-c5739aaa73600755f6c88e3e7d8bbb0d)
至此,我们已经对SocialGraphManager完成了初始化,并为所有端点设置了处理程序,现在是时候通过gorilla路由器将它们公开给外部世界了。每个端点都与一个路由和一个方法相关联,在这种情况下,follow和unfollow操作使用POST方法,而following和followers操作使用GET方法:
![](https://epubservercos.yuewen.com/0B378C/17517093206689306/epubprivate/OEBPS/Images/050-2-i.jpg?sign=1739523666-n1qVMa6vud7FBbUObeOV33Y0XRFsVZdr-0-261c87d4abcb8a0c26e1cd0117679e58)
最后一部分只是将已配置的路由传递给标准HTTP包的ListenAndServe()方法。该服务硬编码为监听端口9090。在本书后面我们将看到如何以一种更灵活且更工业化的方式进行配置:
![](https://epubservercos.yuewen.com/0B378C/17517093206689306/epubprivate/OEBPS/Images/050-3-i.jpg?sign=1739523666-ujak9hrFC2lrBxANmurGfpgdIqqq58qc-0-e2e1245d7ca09d54b9d4b64e84a523d5)