我是如何用go-zero 实现一个中台系统的
<p>最近发现golang社区里出了一个新星的微服务框架,来自好未来,光看这个名字,就很有奔头,之前,也只是玩过go-micro,其实真正的还没有在项目中运用过,只是觉得 微服务,grpc 这些很高大尚,还没有在项目中,真正的玩过,我看了一下官方提供的工具真的很好用,只需要定义好,舒适文件jia结构 都生成了,只需要关心业务,</p><p>加上最近 有个投票的活动,加上最近这几年中台也比较火,所以决定玩一下,</p>
<p>开源地址: https://github.com/jackluo2012/datacenter</p>
<p>先聊聊中台架构思路吧,look 先看架</p>
<p><img src="https://img2020.cnblogs.com/blog/203395/202012/203395-20201217094615171-335437652.jpg" alt="" loading="lazy"></p>
<p>中台的概念大概就是把一个一个的app 统一起来,反正我是这样理解的</p>
<p>先聊用户服务吧,现在一个公司有很多的公众号,小程序,微信的,支付宝的,还有xxx xxx ,很多的平台,每次开发的时候,我们总是需要做用户登陆的服务,不停的复制代码,然后我们就在思考能不能有一套独立的用户服务,</p>
<p>只需要告诉我你需要传个你要登陆的平台(比如微信),微信登陆,需要的是客户端返回给服务端一个code ,然后服务端拿着这个code去微信获取用户信息,反正大家都明白,</p>
<p>我们决定,将所有的信息 弄到 配置公共服务中去,里面在存,微信,支付宝,以及其它平台的 appid ,appkey,还有支付的appid,appkey,</p>
<p>这样就写一套</p>
<p>--------------------------------------------------------------------------------------------</p>
<p>go-zero: https://github.com/tal-tech/go-zero</p>
<p>最后说说实现吧,整个就一个repo </p>
<p>网关,我们用的是: go-zero的Api服务</p>
<p>其它它的是服务,我们就是用的go-zero的rpc服务</p>
<p>看下目录结构</p>
<p><img src="https://img2020.cnblogs.com/blog/203395/202012/203395-20201209110504600-317546535.png" alt="" loading="lazy"></p>
<p>整个项目完成,我一个人操刀, 写了1个来星期,我就实现了上面的中台系统;</p>
<p>go-zero作者私聊我说,可不可以写得丰富点,所以我决定把我的源码也加到文章里面</p>
<p>先看官方文档 https://www.yuque.com/tal-tech/go-zero/yaoehb </p>
<p>我们先把网关搭建起来</p>
<div class="index-module_header_3qjZG">
<div class="index-module_title_1s0gC">
<h1 id="article-title" class="index-module_articleTitle_2xHPX">创建datacenter-api服务</h1>
</div>
</div>
<div class="index-module_content_Sqtvu">
<div class="cnblogs_code">
<p>➜ blogs mkdir datacenter && cd datacenter<br>➜datacenter go mod init datacenter<br>go: creating new go.mod: module datacenter<br>➜datacenter</p>
</div>
<p>查看book目录</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">➜datacenter tree
.
└── go.mod
</span><span style="color: rgba(128, 0, 128, 1)">0</span> directories, <span style="color: rgba(128, 0, 128, 1)">1</span> <span style="color: rgba(0, 0, 255, 1)">file</span></pre>
</div>
<h1 id="7810b09d" data-lake-id="aa3c525ab63107655acc306079f244a9" data-wording="true">二、创建api文件</h1>
<div class="cnblogs_code">
<pre>➜datacenter goctl api -<span style="color: rgba(0, 0, 0, 1)">o datacenter.api
Done.
➜datacenter tree
.
├── datacenter.api
└── go.mod</span></pre>
</div>
<h1 id="cb47c55d" data-lake-id="db478a1eb339dc266283e368832cb86c" data-wording="true">三、定义api服务 分别包含了上面的 公共服务,用户服务,和 投票活动服务</h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">info</span><span style="color: rgba(0, 0, 0, 1)">(
title: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">中台系统</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> TODO: add title</span>
desc: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">中台系统</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> TODO: add description</span>
author: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">jackluo</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
email: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">net.webjoy@gmail.com</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取 应用信息</span>
<span style="color: rgba(0, 0, 0, 1)">type Beid struct {
Beid int64 `json:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">beid</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
}
type Token struct{
Token </span><span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">token</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
}
type WxTicket struct{
Ticket </span><span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">ticket</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
}
type Application struct {
Sname </span><span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Sname</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">名称</span>
Logo <span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">logo</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> login</span>
Isclose int64 `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">isclose</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">是否关闭</span>
Fullwebsite <span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">fullwebsite</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 全站名称</span>
<span style="color: rgba(0, 0, 0, 1)">}
type SnsReq struct{
Beid
Ptyid int64`json:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">ptyid</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">对应平台</span>
BackUrl <span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">back_url</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">登陆返回的地址</span>
<span style="color: rgba(0, 0, 0, 1)">}
type SnsResp struct{
Beid
Ptyid int64`json:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">ptyid</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">对应平台</span>
Appid <span style="color: rgba(0, 0, 255, 1)">string</span>`json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">appid</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">sns 平台的id</span>
Title <span style="color: rgba(0, 0, 255, 1)">string</span>`json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">title</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">名称</span>
LoginUrl <span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">login_url</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">微信登陆的地址</span>
<span style="color: rgba(0, 0, 0, 1)">}
type WxShareResp struct {
Appid </span><span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">appid</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
Timestamp int64 `json:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">timestamp</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
Noncestr </span><span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">noncestr</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
Signature </span><span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">signature</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
}
@server(
group: common
)
service datacenter</span>-<span style="color: rgba(0, 0, 0, 1)">api {
@doc(
summary: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">获取站点的信息</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
)
@handler votesVerification
get </span>/<span style="color: rgba(0, 0, 0, 1)">MP_verify_NT04cqknJe0em3mT.txt (SnsReq) returns (SnsResp)
@handler appInfo
get </span>/common/<span style="color: rgba(0, 0, 0, 1)">appinfo (Beid) returns (Application)
@doc(
summary: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">获取站点的社交属性信息</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
)
@handler snsInfo
post </span>/common/<span style="color: rgba(0, 0, 0, 1)">snsinfo (SnsReq) returns (SnsResp)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取分享的</span>
<span style="color: rgba(0, 0, 0, 1)"> @handler wxTicket
post </span>/common/wx/<span style="color: rgba(0, 0, 0, 1)">ticket (SnsReq) returns (WxShareResp)
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">上传需要登陆</span>
<span style="color: rgba(0, 0, 0, 1)">@server(
jwt: Auth
group: common
)
service datacenter</span>-<span style="color: rgba(0, 0, 0, 1)">api {
@doc(
summary: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">七牛上传凭证</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
)
@handler qiuniuToken
post </span>/common/qiuniu/<span style="color: rgba(0, 0, 0, 1)">token (Beid) returns (Token)
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">注册请求</span>
<span style="color: rgba(0, 0, 0, 1)">type RegisterReq struct {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> TODO: add members here and delete this comment</span>
Mobile <span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">mobile</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">基本一个手机号码就完事</span>
Password <span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">password</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
Smscode </span><span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">smscode</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">短信码</span>
<span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">登陆请求</span>
<span style="color: rgba(0, 0, 0, 1)">type LoginReq struct{
Mobile </span><span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">mobile</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
Type int64 `json:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">type</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">1.密码登陆,2.短信登陆</span>
Password <span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">password</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">微信登陆</span>
<span style="color: rgba(0, 0, 0, 1)">type WxLoginReq struct {
Beid int64`json:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">beid</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">应用id</span>
Code <span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">code</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">微信登陆密钥</span>
Ptyid int64`json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">ptyid</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">对应平台</span>
<span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">返回用户信息</span>
<span style="color: rgba(0, 0, 0, 1)">type UserReply struct {
Auid int64`json:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">auid</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
Uid int64`json:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">uid</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
Beid int64`json:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">beid</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">应用id</span>
Ptyid int64`json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">ptyid</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">对应平台</span>
Username <span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">username</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
Mobile </span><span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">mobile</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
Nickname </span><span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">nickname</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
Openid </span><span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">openid</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
Avator </span><span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">avator</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
JwtToken
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">返回APPUser</span>
<span style="color: rgba(0, 0, 0, 1)">type AppUser struct{
Uid int64`json:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">uid</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
Auid int64`json:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">auid</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
Beid int64`json:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">beid</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">应用id</span>
Ptyid int64`json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">ptyid</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">对应平台</span>
Nickname <span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">nickname</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
Openid </span><span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">openid</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
Avator </span><span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">avator</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
}
type LoginAppUser struct{
Uid int64`json:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">uid</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
Auid int64`json:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">auid</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
Beid int64`json:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">beid</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">应用id</span>
Ptyid int64`json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">ptyid</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">对应平台</span>
Nickname <span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">nickname</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
Openid </span><span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">openid</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
Avator </span><span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">avator</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
JwtToken
}
type JwtToken struct {
AccessToken</span><span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">access_token,omitempty</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
AccessExpire int64`json:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">access_expire,omitempty</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
RefreshAfter int64`json:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">refresh_after,omitempty</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
}
type UserReq struct{
Auid int64`json:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">auid</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
Uid int64`json:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">uid</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
Beid int64`json:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">beid</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">应用id</span>
Ptyid int64`json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">ptyid</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">对应平台</span>
<span style="color: rgba(0, 0, 0, 1)">}
type Request {
Name </span><span style="color: rgba(0, 0, 255, 1)">string</span> `path:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">name,options=you|me</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
}
type Response {
Message </span><span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">message</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
}
@server(
group: user
)
service user</span>-<span style="color: rgba(0, 0, 0, 1)">api {
@handler </span><span style="color: rgba(0, 0, 255, 1)">ping</span><span style="color: rgba(0, 0, 0, 1)">
post </span>/user/<span style="color: rgba(0, 0, 255, 1)">ping</span><span style="color: rgba(0, 0, 0, 1)"> ()
@handler register
post </span>/user/<span style="color: rgba(0, 0, 0, 1)">register (RegisterReq) returns (UserReply)
@handler </span><span style="color: rgba(0, 0, 255, 1)">login</span><span style="color: rgba(0, 0, 0, 1)">
post </span>/user/<span style="color: rgba(0, 0, 255, 1)">login</span><span style="color: rgba(0, 0, 0, 1)"> (LoginReq) returns (UserReply)
@handler wxlogin
post </span>/user/wx/<span style="color: rgba(0, 0, 255, 1)">login</span><span style="color: rgba(0, 0, 0, 1)"> (WxLoginReq) returns (LoginAppUser)
@handler code2Session
get </span>/user/wx/<span style="color: rgba(0, 0, 255, 1)">login</span><span style="color: rgba(0, 0, 0, 1)"> () returns (LoginAppUser)
}
@server(
jwt: Auth
group: user
middleware: Usercheck
)
service user</span>-<span style="color: rgba(0, 0, 0, 1)">api {
@handler userInfo
get </span>/user/dc/<span style="color: rgba(0, 0, 255, 1)">info</span><span style="color: rgba(0, 0, 0, 1)"> (UserReq) returns (UserReply)
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 投票活动api</span>
<span style="color: rgba(0, 0, 0, 1)">
type Actid struct {
Actid int64`json:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">actid</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">活动id</span>
<span style="color: rgba(0, 0, 0, 1)">}
type VoteReq struct {
Aeid int64`json:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">aeid</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 作品id</span>
<span style="color: rgba(0, 0, 0, 1)"> Actid
}
type VoteResp struct {
VoteReq
Votecount int64`json:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">votecount</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">投票票数</span>
Viewcount int64`json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">viewcount</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">浏览数</span>
<span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 活动返回的参数</span>
<span style="color: rgba(0, 0, 0, 1)">
type ActivityResp struct {
Actid int64`json:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">actid</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
Title </span><span style="color: rgba(0, 0, 255, 1)">string</span>`json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">title</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">活动名称</span>
Descr <span style="color: rgba(0, 0, 255, 1)">string</span>`json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">descr</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">活动描述</span>
StartDate int64`json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">start_date</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">活动时间</span>
EnrollDate int64`json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">enroll_date</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">投票时间</span>
EndDate int64`json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">end_date</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">活动结束时间</span>
Votecount int64`json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">votecount</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">当前活动的总票数</span>
Viewcount int64`json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">viewcount</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">当前活动的总浏览数</span>
Type int64 `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">type</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">投票方式</span>
Num int64 `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">num</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">投票几票</span>
<span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">报名</span>
<span style="color: rgba(0, 0, 0, 1)">
type EnrollReq struct {
Actid
Name </span><span style="color: rgba(0, 0, 255, 1)">string</span>`json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">name</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 名称</span>
Address <span style="color: rgba(0, 0, 255, 1)">string</span>`json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">address</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">地址</span>
Images []<span style="color: rgba(0, 0, 255, 1)">string</span>`json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">images</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">作品图片</span>
Descr <span style="color: rgba(0, 0, 255, 1)">string</span>`json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">descr</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 作品描述</span>
<span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 作品返回</span>
<span style="color: rgba(0, 0, 0, 1)">
type EnrollResp struct {
Actid
Aeid int64 `json:</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">aeid</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 作品id</span>
Name <span style="color: rgba(0, 0, 255, 1)">string</span>`json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">name</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 名称</span>
Address <span style="color: rgba(0, 0, 255, 1)">string</span>`json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">address</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">地址</span>
Images []<span style="color: rgba(0, 0, 255, 1)">string</span>`json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">images</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">作品图片</span>
Descr <span style="color: rgba(0, 0, 255, 1)">string</span>`json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">descr</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 作品描述</span>
Votecount int64`json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">votecount</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">当前活动的总票数</span>
Viewcount int64`json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">viewcount</span><span style="color: rgba(128, 0, 0, 1)">"</span>` <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">当前活动的总浏览数</span>
<span style="color: rgba(0, 0, 0, 1)">
}
@server(
group: votes
)
service votes</span>-<span style="color: rgba(0, 0, 0, 1)">api {
@doc(
summary: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">获取活动的信息</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
)
@handler activityInfo
get </span>/votes/activity/<span style="color: rgba(0, 0, 255, 1)">info</span><span style="color: rgba(0, 0, 0, 1)"> (Actid) returns (ActivityResp)
@doc(
summary: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">活动访问+1</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
)
@handler activityIcrView
get </span>/votes/activity/<span style="color: rgba(0, 0, 0, 1)">view (Actid) returns (ActivityResp)
@doc(
summary: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">获取报名的投票作品信息</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
)
@handler enrollInfo
get </span>/votes/enroll/<span style="color: rgba(0, 0, 255, 1)">info</span><span style="color: rgba(0, 0, 0, 1)"> (VoteReq) returns (EnrollResp)
@doc(
summary: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">获取报名的投票作品列表</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
)
@handler enrollLists
get </span>/votes/enroll/<span style="color: rgba(0, 0, 0, 1)">lists (Actid) returns(EnrollResp)
}
@server(
jwt: Auth
group: votes
middleware: Usercheck
)
service votes</span>-<span style="color: rgba(0, 0, 0, 1)">api {
@doc(
summary: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">投票</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
)
@handler vote
post </span>/votes/<span style="color: rgba(0, 0, 0, 1)">vote (VoteReq) returns (VoteResp)
@handler enroll
post </span>/votes/<span style="color: rgba(0, 0, 0, 1)">enroll (EnrollReq) returns (EnrollResp)
}</span></pre>
</div>
<p>上面基本上写就写的API及文档的思路</p>
<h1 id="c3018b1e" data-lake-id="54c204d65580d0385d68c4b3dc5040ef" data-wording="true">四、生成datacenter api服务</h1>
</div>
<div class="cnblogs_code">
<pre>➜datacenter goctl api go -api datacenter.api -<span style="color: rgba(0, 0, 255, 1)">dir</span><span style="color: rgba(0, 0, 0, 1)"> .
Done.
➜datacenter tree
.
├── datacenter.api
├── etc
│ └── datacenter</span>-<span style="color: rgba(0, 0, 0, 1)">api.yaml
├── go.mod
├── internal
│ ├── config
│ │ └── config.go
│ ├── handler
│ │ ├── common
│ │ │ ├── appinfohandler.go
│ │ │ ├── qiuniutokenhandler.go
│ │ │ ├── snsinfohandler.go
│ │ │ ├── votesverificationhandler.go
│ │ │ └── wxtickethandler.go
│ │ ├── routes.go
│ │ ├── user
│ │ │ ├── code2sessionhandler.go
│ │ │ ├── loginhandler.go
│ │ │ ├── pinghandler.go
│ │ │ ├── registerhandler.go
│ │ │ ├── userinfohandler.go
│ │ │ └── wxloginhandler.go
│ │ └── votes
│ │ ├── activityicrviewhandler.go
│ │ ├── activityinfohandler.go
│ │ ├── enrollhandler.go
│ │ ├── enrollinfohandler.go
│ │ ├── enrolllistshandler.go
│ │ └── votehandler.go
│ ├── logic
│ │ ├── common
│ │ │ ├── appinfologic.go
│ │ │ ├── qiuniutokenlogic.go
│ │ │ ├── snsinfologic.go
│ │ │ ├── votesverificationlogic.go
│ │ │ └── wxticketlogic.go
│ │ ├── user
│ │ │ ├── code2sessionlogic.go
│ │ │ ├── loginlogic.go
│ │ │ ├── pinglogic.go
│ │ │ ├── registerlogic.go
│ │ │ ├── userinfologic.go
│ │ │ └── wxloginlogic.go
│ │ └── votes
│ │ ├── activityicrviewlogic.go
│ │ ├── activityinfologic.go
│ │ ├── enrollinfologic.go
│ │ ├── enrolllistslogic.go
│ │ ├── enrolllogic.go
│ │ └── votelogic.go
│ ├── middleware
│ │ └── usercheckmiddleware.go
│ ├── svc
│ │ └── servicecontext.go
│ └── types
│ └── types.go
└── datacenter.go
</span><span style="color: rgba(128, 0, 128, 1)">14</span> directories, <span style="color: rgba(128, 0, 128, 1)">43</span> files</pre>
</div>
<p>我们打开etc/datacenter-api.yaml 把必要的配置信息加上</p>
<div class="cnblogs_code">
<pre>Name: datacenter-<span style="color: rgba(0, 0, 0, 1)">api
Log:
Mode: console
Host: </span><span style="color: rgba(128, 0, 128, 1)">0.0</span>.<span style="color: rgba(128, 0, 128, 1)">0.0</span><span style="color: rgba(0, 0, 0, 1)">
Port: </span><span style="color: rgba(128, 0, 128, 1)">8857</span><span style="color: rgba(0, 0, 0, 1)">
Auth:
AccessSecret: 你的jwtwon Secret</span><span style="color: rgba(0, 0, 0, 1)">
AccessExpire: </span><span style="color: rgba(128, 0, 128, 1)">86400</span><span style="color: rgba(0, 0, 0, 1)">
CacheRedis:
</span>- Host: <span style="color: rgba(128, 0, 128, 1)">127.0</span>.<span style="color: rgba(128, 0, 128, 1)">0.1</span>:<span style="color: rgba(128, 0, 128, 1)">6379</span><span style="color: rgba(0, 0, 0, 1)">
Pass: 密码
Type: node </span><span style="color: rgba(0, 0, 0, 1)">
UserRpc:
Etcd:
Hosts:
</span>- <span style="color: rgba(128, 0, 128, 1)">127.0</span>.<span style="color: rgba(128, 0, 128, 1)">0.1</span>:<span style="color: rgba(128, 0, 128, 1)">2379</span><span style="color: rgba(0, 0, 0, 1)">
Key: user.rpc
CommonRpc:
Etcd:
Hosts:
</span>- <span style="color: rgba(128, 0, 128, 1)">127.0</span>.<span style="color: rgba(128, 0, 128, 1)">0.1</span>:<span style="color: rgba(128, 0, 128, 1)">2379</span><span style="color: rgba(0, 0, 0, 1)">
Key: common.rpc
VotesRpc:
Etcd:
Hosts:
</span>- <span style="color: rgba(128, 0, 128, 1)">127.0</span>.<span style="color: rgba(128, 0, 128, 1)">0.1</span>:<span style="color: rgba(128, 0, 128, 1)">2379</span><span style="color: rgba(0, 0, 0, 1)">
Key: votes.rpc </span></pre>
</div>
<p>上面的 UserRpc,和 CommonRpc ,还有VotesRpc 这些我先写上,后面再来慢慢加</p>
<p>我们先来写CommonRpc的服务</p>
<h3 id="Sn3vs" data-lake-id="153d30d45e77ae609fb8969f6fe40f93" data-wording="true">新建项目目录</h3>
<div class="cnblogs_code">
<pre>➜datacenter <span style="color: rgba(0, 0, 255, 1)">mkdir -p</span> common/rpc && cd common/rpc</pre>
</div>
<p>直接就新建在了,datacenter目录中,因为common 里面,可能以后会不只会提供rpc服务,可能还有api的服务,所以又加了rpc目录</p>
<h3 id="QPKjm" data-lake-id="0a10b874431d9e912fb4ed156c8cda48" data-wording="true">goctl创建模板</h3>
<div class="cnblogs_code">
<pre>➜rpc goctl rpc template -o=<span style="color: rgba(0, 0, 0, 1)">common.proto
➜rpc </span><span style="color: rgba(0, 0, 255, 1)">ls</span><span style="color: rgba(0, 0, 0, 1)">
common.proto</span></pre>
</div>
<p>往里面填入内容</p>
<div class="cnblogs_code">
<pre>➜rpc <span style="color: rgba(0, 0, 255, 1)">cat</span> <span style="color: rgba(0, 0, 0, 1)">common.proto
syntax </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">proto3</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
package common;
message BaseAppReq{
int64 beid</span>=<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
}
message BaseAppResp{
int64 beid</span>=<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">string</span> logo=<span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">string</span> sname=<span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">;
int64 isclose</span>=<span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">string</span> fullwebsite=<span style="color: rgba(128, 0, 128, 1)">5</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">请求的api</span>
<span style="color: rgba(0, 0, 0, 1)">message AppConfigReq {
int64 beid</span>=<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
int64 ptyid</span>=<span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">返回的值</span>
<span style="color: rgba(0, 0, 0, 1)">message AppConfigResp {
int64 </span><span style="color: rgba(0, 0, 255, 1)">id</span>=<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
int64 beid</span>=<span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">;
int64 ptyid</span>=<span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">string</span> appid=<span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">string</span> appsecret=<span style="color: rgba(128, 0, 128, 1)">5</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">string</span> title=<span style="color: rgba(128, 0, 128, 1)">6</span><span style="color: rgba(0, 0, 0, 1)">;
}
service Common {
rpc GetAppConfig(AppConfigReq) returns(AppConfigResp);
rpc GetBaseApp(BaseAppReq) returns(BaseAppResp);
}</span></pre>
</div>
<p> </p>
<h3 id="C4NRo" data-lake-id="32463a77db92c00b7ab12c0c451a32bc" data-wording="true">gotcl生成rpc服务</h3>
<div class="cnblogs_code">
<pre>➜rpc goctl rpc proto -src common.proto -<span style="color: rgba(0, 0, 255, 1)">dir</span><span style="color: rgba(0, 0, 0, 1)"> .
protoc</span>-I=/Users/jackluo/works/blogs/datacenter/common/rpc common.proto --go_out=plugins=grpc:/Users/jackluo/works/blogs/datacenter/common/rpc/<span style="color: rgba(0, 0, 0, 1)">common
Done.<br></span></pre>
<p>➜ rpc tree<br>.<br>├── common<br>│ └── common.pb.go<br>├── common.go<br>├── common.proto<br>├── commonclient<br>│ └── common.go<br>├── etc<br>│ └── common.yaml<br>└── internal<br> ├── config<br> │ └── config.go<br> ├── logic<br> │ ├── getappconfiglogic.go<br> │ └── getbaseapplogic.go<br> ├── server<br> │ └── commonserver.go<br> └── svc<br> └── servicecontext.go</p>
<pre></pre>
<p>8 directories, 10 files</p>
<pre><span style="color: rgba(0, 0, 0, 1)"> </span></pre>
</div>
<p>基本上,就把所有的目录规范和结构的东西都生成了,就不用纠结项目目录了,怎么放了,怎么组织了</p>
<p>看一下,配置信息,里面可以写入mysql和其它redis的信息</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">Name: common.rpc
ListenOn: </span><span style="color: rgba(128, 0, 128, 1)">127.0</span>.<span style="color: rgba(128, 0, 128, 1)">0.1</span>:<span style="color: rgba(128, 0, 128, 1)">8081</span><span style="color: rgba(0, 0, 0, 1)">
Mysql:
DataSource: root:admin@tcp(</span><span style="color: rgba(128, 0, 128, 1)">127.0</span>.<span style="color: rgba(128, 0, 128, 1)">0.1</span>:<span style="color: rgba(128, 0, 128, 1)">3306</span>)/datacenter?charset=utf8&parseTime=<span style="color: rgba(0, 0, 255, 1)">true</span>&loc=Asia%<span style="color: rgba(0, 0, 0, 1)">2FShanghai
CacheRedis:
</span>- Host: <span style="color: rgba(128, 0, 128, 1)">127.0</span>.<span style="color: rgba(128, 0, 128, 1)">0.1</span>:<span style="color: rgba(128, 0, 128, 1)">6379</span><span style="color: rgba(0, 0, 0, 1)">
Pass:
Type: node
Etcd:
Hosts:
</span>- <span style="color: rgba(128, 0, 128, 1)">127.0</span>.<span style="color: rgba(128, 0, 128, 1)">0.1</span>:<span style="color: rgba(128, 0, 128, 1)">2379</span><span style="color: rgba(0, 0, 0, 1)">
Key: common.rpc</span></pre>
</div>
<p>我们再来加上数据库的服务</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">➜rpc cd ..
➜common </span><span style="color: rgba(0, 0, 255, 1)">ls</span><span style="color: rgba(0, 0, 0, 1)">
rpc
➜common </span><span style="color: rgba(0, 0, 255, 1)">pwd</span>
/Users/jackluo/works/blogs/datacenter/<span style="color: rgba(0, 0, 0, 1)">common
➜common goctl model mysql datasource </span>-url=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">root:admin@tcp(127.0.0.1:3306)/datacenter</span><span style="color: rgba(128, 0, 0, 1)">"</span> -table=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">base_app</span><span style="color: rgba(128, 0, 0, 1)">"</span> -<span style="color: rgba(0, 0, 255, 1)">dir</span> ./model -<span style="color: rgba(0, 0, 0, 1)">c
Done.
➜common tree
.
├── model
│ ├── baseappmodel.go
│ └── vars.go
└── rpc
├── common
│ └── common.pb.go
├── common.go
├── common.proto
├── commonclient
│ └── common.go
├── etc
│ └── common.yaml
└── internal
├── config
│ └── config.go
├── logic
│ ├── getappconfiglogic.go
│ └── getbaseapplogic.go
├── server
│ └── commonserver.go
└── svc
└── servicecontext.go
</span><span style="color: rgba(128, 0, 128, 1)">10</span> directories, <span style="color: rgba(128, 0, 128, 1)">12</span> files</pre>
</div>
<p>这样基本的一个rpc就写完了,然后我们将rpc 和model 还有api串连起来,这个官方的文档已经很详细了,这里就只是贴一下代码</p>
<div class="cnblogs_code">
<pre>➜common <span style="color: rgba(0, 0, 255, 1)">cat</span> rpc/internal/config/<span style="color: rgba(0, 0, 0, 1)">config.go
package config
import (
</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">github.com/tal-tech/go-zero/core/stores/cache</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">github.com/tal-tech/go-zero/zrpc</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
)
type Config struct {
zrpc.RpcServerConf
Mysql struct {
DataSource </span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">
}
CacheRedis cache.ClusterConf
}</span></pre>
</div>
<p>再在svc中修改</p>
<div class="cnblogs_code">
<pre>➜common <span style="color: rgba(0, 0, 255, 1)">cat</span> rpc/internal/svc/<span style="color: rgba(0, 0, 0, 1)">servicecontext.go
package svc
import (
</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">datacenter/common/model</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">datacenter/common/rpc/internal/config</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">github.com/tal-tech/go-zero/core/stores/sqlx</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
)
type ServiceContext struct {
c config.Config
AppConfigModel model.AppConfigModel
BaseAppModel model.BaseAppModel
}
func NewServiceContext(c config.Config) </span>*<span style="color: rgba(0, 0, 0, 1)">ServiceContext {
conn :</span>=<span style="color: rgba(0, 0, 0, 1)"> sqlx.NewMysql(c.Mysql.DataSource)
apm :</span>=<span style="color: rgba(0, 0, 0, 1)"> model.NewAppConfigModel(conn, c.CacheRedis)
bam :</span>=<span style="color: rgba(0, 0, 0, 1)"> model.NewBaseAppModel(conn, c.CacheRedis)
return </span>&<span style="color: rgba(0, 0, 0, 1)">ServiceContext{
c: c,
AppConfigModel: apm,
BaseAppModel: bam,
}
}</span></pre>
</div>
<p>上面的代码已经将rpc 和 model 数据库关联起来了,我们现在再将rpc 和 api关联起来</p>
<div class="cnblogs_code">
<pre>➜datacenter <span style="color: rgba(0, 0, 255, 1)">cat</span> internal/config/<span style="color: rgba(0, 0, 0, 1)">config.go
package config
import (
</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">github.com/tal-tech/go-zero/core/stores/cache</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">github.com/tal-tech/go-zero/rest</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">github.com/tal-tech/go-zero/zrpc</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
)
type Config struct {
rest.RestConf
Auth struct {
AccessSecret </span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">
AccessExpire int64
}
UserRpc zrpc.RpcClientConf
CommonRpc zrpc.RpcClientConf
VotesRpczrpc.RpcClientConf
CacheRedis cache.ClusterConf
}</span></pre>
</div>
<p>加入svc服务中</p>
<div class="cnblogs_code">
<pre>➜datacenter <span style="color: rgba(0, 0, 255, 1)">cat</span> internal/svc/<span style="color: rgba(0, 0, 0, 1)">servicecontext.go
package svc
import (
</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">context</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">datacenter/common/rpc/commonclient</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">datacenter/internal/config</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">datacenter/internal/middleware</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">datacenter/shared</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">datacenter/user/rpc/userclient</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">datacenter/votes/rpc/votesclient</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">fmt</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">net/http</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">time</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">github.com/tal-tech/go-zero/core/logx</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">github.com/tal-tech/go-zero/core/stores/cache</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">github.com/tal-tech/go-zero/core/stores/redis</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">github.com/tal-tech/go-zero/core/syncx</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">github.com/tal-tech/go-zero/rest</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">github.com/tal-tech/go-zero/zrpc</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">google.golang.org/grpc</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
)
type ServiceContext struct {
Config config.Config
GreetMiddleware1 rest.Middleware
GreetMiddleware2 rest.Middleware
Usercheck rest.Middleware
UserRpc userclient.User </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">用户</span>
<span style="color: rgba(0, 0, 0, 1)"> CommonRpc commonclient.Common
VotesRpc votesclient.Votes
Cache cache.Cache
RedisConn </span>*<span style="color: rgba(0, 0, 0, 1)">redis.Redis
}
func timeInterceptor(ctx context.Context, method </span><span style="color: rgba(0, 0, 255, 1)">string</span>, req, reply interface{}, <span style="color: rgba(0, 0, 255, 1)">cc</span> *<span style="color: rgba(0, 0, 0, 1)">grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
stime :</span>= <span style="color: rgba(0, 0, 255, 1)">time</span><span style="color: rgba(0, 0, 0, 1)">.Now()
err :</span>= invoker(ctx, method, req, reply, <span style="color: rgba(0, 0, 255, 1)">cc</span><span style="color: rgba(0, 0, 0, 1)">, opts...)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
return err
}
</span><span style="color: rgba(0, 0, 255, 1)">fmt</span>.Printf(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">调用 %s 方法 耗时: %v\n</span><span style="color: rgba(128, 0, 0, 1)">"</span>, method, <span style="color: rgba(0, 0, 255, 1)">time</span><span style="color: rgba(0, 0, 0, 1)">.Now().Sub(stime))
return nil
}
func NewServiceContext(c config.Config) </span>*<span style="color: rgba(0, 0, 0, 1)">ServiceContext {
ur :</span>=<span style="color: rgba(0, 0, 0, 1)"> userclient.NewUser(zrpc.MustNewClient(c.UserRpc, zrpc.WithUnaryClientInterceptor(timeInterceptor)))
cr :</span>=<span style="color: rgba(0, 0, 0, 1)"> commonclient.NewCommon(zrpc.MustNewClient(c.CommonRpc, zrpc.WithUnaryClientInterceptor(timeInterceptor)))
vr :</span>=<span style="color: rgba(0, 0, 0, 1)"> votesclient.NewVotes(zrpc.MustNewClient(c.VotesRpc, zrpc.WithUnaryClientInterceptor(timeInterceptor)))
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">缓存</span>
ca := cache.NewCache(c.CacheRedis, syncx.NewSharedCalls(), cache.NewCacheStat(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">dc</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">), shared.ErrNotFound)
rcon :</span>= redis.NewRedis(c.CacheRedis[<span style="color: rgba(128, 0, 128, 1)">0</span>].Host, c.CacheRedis[<span style="color: rgba(128, 0, 128, 1)">0</span>].Type, c.CacheRedis[<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">].Pass)
return </span>&<span style="color: rgba(0, 0, 0, 1)">ServiceContext{
Config: c,
GreetMiddleware1: greetMiddleware1,
GreetMiddleware2: greetMiddleware2,
Usercheck: middleware.NewUserCheckMiddleware().Handle,
UserRpc: ur,
CommonRpc: cr,
VotesRpc: vr,
Cache: ca,
RedisConn: rcon,
}
}</span></pre>
</div>
<p>这样基本上,我们就可以在logic的文件目录中调用了</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">cat</span> internal/logic/common/<span style="color: rgba(0, 0, 0, 1)">appinfologic.go
package logic
import (
</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">context</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">datacenter/internal/svc</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">datacenter/internal/types</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">datacenter/shared</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">datacenter/common/model</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">datacenter/common/rpc/common</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">github.com/tal-tech/go-zero/core/logx</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
)
type AppInfoLogic struct {
logx.Logger
ctx context.Context
svcCtx </span>*<span style="color: rgba(0, 0, 0, 1)">svc.ServiceContext
}
func NewAppInfoLogic(ctx context.Context, svcCtx </span>*<span style="color: rgba(0, 0, 0, 1)">svc.ServiceContext) AppInfoLogic {
return AppInfoLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l </span>*AppInfoLogic) AppInfo(req types.Beid) (appconfig *<span style="color: rgba(0, 0, 0, 1)">common.BaseAppResp, err error) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">检查 缓存中是否有值</span>
err =<span style="color: rgba(0, 0, 0, 1)"> l.svcCtx.Cache.GetCache(model.GetcacheBaseAppIdPrefix(req.Beid), appconfig)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err != nil && err ==<span style="color: rgba(0, 0, 0, 1)"> shared.ErrNotFound {
appconfig, err </span>= l.svcCtx.CommonRpc.GetBaseApp(l.ctx, &<span style="color: rgba(0, 0, 0, 1)">common.BaseAppReq{
Beid: req.Beid,
})
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
return
}
err </span>=<span style="color: rgba(0, 0, 0, 1)"> l.svcCtx.Cache.SetCache(model.GetcacheBaseAppIdPrefix(req.Beid), appconfig)
}
return
}</span></pre>
</div>
<p>这样,基本就连接起来了,其它基本上就不用改了,UserRPC,和VotesRPC类似,这里就不在写了</p>
<h1 id="a0cce463" data-lake-id="358a83899c466cbdbf17b7b06de39467" data-wording="true">下面我说说使用心得吧</h1>
<p>go-zero 的确香,因为它有一个goctl 的工具,他可以自动的把代码结构全部的生成好,我们就不再去纠结,目录结构 ,怎么组织,没有个好几年的架构能力是不好实现的,有什么规范那些,并发,熔断,完全不用,考滤其它的,专心的实现业务就好,像微服务,还要有服务发现,一系列的东西,都不用关心,因为go-zero内部已经实现了,我写代码也写了有10多年了,之前一直用的php,比较出名的就 laravel,thinkphp,基本上就是模块化的,像微服那些实现直来真的有成本,但是你用上go-zero,你就像调api接口一样简单的开发,其它什么服务发现,那些根本就不用关注了,只需要关注业务。一个好的语言,框架,他们的底层思维,永远都是效率高,不加班的思想,我相信go-zero会提高你和你团队或是公司的效率。go-zero的作者说,他们有个团队专门整理go-zero框架,目的也应该很明显,那就是提高,他们自己的开发效率,流程化,标准化,是提高工作效率的准则,像我们平时遇到了问题,或是遇到了bug,我第一个想到的不是怎么去解决我的bug,而是在想我的流程是不是有问题,我的哪个流程会导致bug,最后我相信go-zero 能成为 微服务开发 的首选框架</p>
<p>最后说说遇到的坑吧:</p>
<p>grpc 本人第一次用,然后就遇到了,有些字符为空时,字段值不显示的问题:</p>
<p>通过grpc官方库中的<code>jsonpb</code>来实现,官方在它的设定中有一个结构体用来实现<code>protoc buffer</code>转换为JSON结构,并可以根据字段来配置转换的要求</p>
<p>跨域问题:</p>
<p>go-zero的设置了,感觉没有效果,大佬说通过nginx 设置,后面发现还是不行,最近 ,强行弄到了一个域名下,后面有时间再解决</p>
<p>go-zero的sqlx 问题,这个真的费了很长的时间,</p>
<div class="cnblogs_code">
<pre>time.Time 这个数据结构,数据库中用的是 timestamp 这个 比如我的字段 是delete_at 默认数库设置的是null ,结果插入的时候,<br>就报了Incorrect datetime value: '0000-00-00' for column 'deleted_at' at row 1"}这个错,<br>查询的时候报deleted_at\": unsupported Scan, storing driver.Value type \u003cnil\u003e into type *time.Time" <br>后面果断去掉了这个字段<br>字段上面加上 .omitempty 这个标签,好像也有用,`db:".omitempty"`</pre>
</div>
<p>其次就是这个 Conversion from collation utf8_general_ci into utf8mb4_unicode_ci,这个导致的大概原因是,现在都喜欢用emj表情了,mysql数据识别不了</p>
<p>最后发现是数据连接问题:</p>
<p>mysql这边照样按照原始的方式,将配置文件修改编码格式<br>重新创建数据库,并且设置数据库编码为utf8mb4 ,排序规则为utf8mb4_unicode_ci<br>(这样的话,所有的表还有string字段都是这个编码格式,如果不想所有的都是,可以单独设置,这个不是重点.因为在navicat上都好设置,手动点一下就行了)<br>重点来了:golang中使用的是 github.com/go-sql-driver/mysql驱动,<br>将连接mysql的dsn:(因为我这使用的是gorm,所以dsn可能跟原生的格式不太一样,不过没关系,只需要关注charset和collation就行了)<br>root:password@/name?parseTime=True&loc=Local&charset=utf8<br>修改为:<br>root:password@/name?parseTime=True&loc=Local&charset=utf8mb4&collation=utf8mb4_unicode_ci</p>
<p>---------------------------------</p>
<p>mark</p>
<p> </p><br><br>
来源:https://www.cnblogs.com/jackluo/p/14148518.html
頁:
[1]