牛角包 發表於 2019-11-7 14:13:00

go-micro+php+consul简单的微服实现

<p>&nbsp;</p>
<div>
<p>首先我们用go-micro构建一个服务。(关于go-micro的使用可以参照官方实例或者文档)</p>
<div class="highlight">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">新建一个微服务</span>
micro <span style="color: rgba(0, 0, 255, 1)">new</span> --type "srv" user-srv</pre>
</div>
<p>&nbsp;</p>
<pre><span style="font-family: &quot;PingFang SC&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-size: 14px">定义我们的服务,这里定义两个rpc服务,Register和User</span></pre>
</div>
<div class="highlight">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 修改proto</span>
<span style="color: rgba(0, 128, 128, 1)"> 2</span> syntax = "proto3"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> package go.micro.srv.<span style="color: rgba(0, 0, 0, 1)">user;
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 0, 1)">service User {
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)">    rpc Register(RegisterRequest) returns (UserInfo) {}
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 0, 1)">    rpc User(UserInfoRequest) returns (UserInfo) {}
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)">    rpc Stream(StreamingRequest) returns (stream StreamingResponse) {}
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 0, 1)">    rpc PingPong(stream Ping) returns (stream Pong) {}
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)">13</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)">14</span> <span style="color: rgba(0, 0, 0, 1)">message UserInfoRequest {
</span><span style="color: rgba(0, 128, 128, 1)">15</span>   int64 userId= 1<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">16</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">17</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)">18</span> <span style="color: rgba(0, 0, 0, 1)">message RegisterRequest {
</span><span style="color: rgba(0, 128, 128, 1)">19</span>   <span style="color: rgba(0, 0, 255, 1)">string</span> username= 1<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">20</span>   <span style="color: rgba(0, 0, 255, 1)">string</span> email   = 2<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">21</span>   <span style="color: rgba(0, 0, 255, 1)">string</span> password= 3<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">22</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">23</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)">24</span> <span style="color: rgba(0, 0, 0, 1)">message UserInfo {
</span><span style="color: rgba(0, 128, 128, 1)">25</span>   int64id       =1<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">26</span>   <span style="color: rgba(0, 0, 255, 1)">string</span> username =2<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">27</span>   <span style="color: rgba(0, 0, 255, 1)">string</span> email    =3<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">28</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">29</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)">30</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)">31</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)">32</span> <span style="color: rgba(0, 0, 0, 1)">message StreamingRequest {
</span><span style="color: rgba(0, 128, 128, 1)">33</span>   int64 <span style="color: rgba(0, 128, 128, 1)">count</span> = 1<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">34</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">35</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)">36</span> <span style="color: rgba(0, 0, 0, 1)">message StreamingResponse {
</span><span style="color: rgba(0, 128, 128, 1)">37</span>   int64 <span style="color: rgba(0, 128, 128, 1)">count</span> = 1<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">38</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">39</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)">40</span> <span style="color: rgba(0, 0, 0, 1)">message Ping {
</span><span style="color: rgba(0, 128, 128, 1)">41</span>   int64 stroke = 1<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">42</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">43</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)">44</span> <span style="color: rgba(0, 0, 0, 1)">message Pong {
</span><span style="color: rgba(0, 128, 128, 1)">45</span>   int64 stroke = 1<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">46</span> }</pre>
</div>
<p>&nbsp;</p>
</div>
<p>然后生成执行下面命令我们就可以发现在proto文件中多出两个文件。这个proto为我们生成的,后面会用到。</p>
<div class="highlight">
<div class="cnblogs_code">
<pre>protoc --proto_path=${GOPATH}/src:. --micro_out=. --go_out=. proto/user/user.proto</pre>
</div>
<p>&nbsp;</p>
</div>
<p>写我们的业务逻辑,修改handle/user.go文件</p>
<div class="highlight">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 0, 0, 1)">type User struct{}
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Call is a single request handler called via client.Call or the generated client code</span>
<span style="color: rgba(0, 128, 128, 1)"> 4</span> func (e *User) Register(ctx context.Context, req *user.RegisterRequest, rsp *user.<span style="color: rgba(0, 0, 0, 1)">UserInfo) error {
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span>   <span style="color: rgba(0, 128, 128, 1)">log</span>.<span style="color: rgba(0, 128, 128, 1)">Log</span>("Received User.Register request"<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span>   rsp.Id    = 1
<span style="color: rgba(0, 128, 128, 1)"> 7</span>   rsp.Email = req.<span style="color: rgba(0, 0, 0, 1)">Email
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span>   rsp.Username = req.<span style="color: rgba(0, 0, 0, 1)">Username
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span>   <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> nil
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)">13</span> func (e *User) User(ctx context.Context, req *user.UserInfoRequest, rsp *user.<span style="color: rgba(0, 0, 0, 1)">UserInfo) error {
</span><span style="color: rgba(0, 128, 128, 1)">14</span>   <span style="color: rgba(0, 128, 128, 1)">log</span>.<span style="color: rgba(0, 128, 128, 1)">Log</span>("Received User.Register request"<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">15</span>   rsp.Id    = 1
<span style="color: rgba(0, 128, 128, 1)">16</span>   rsp.Email = "741001560@qq.com"
<span style="color: rgba(0, 128, 128, 1)">17</span>   rsp.Username = "chensi"
<span style="color: rgba(0, 128, 128, 1)">18</span>   <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> nil
</span><span style="color: rgba(0, 128, 128, 1)">19</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">20</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)">21</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Stream is a server side stream handler called via client.Stream or the generated client code</span>
<span style="color: rgba(0, 128, 128, 1)">22</span> func (e *User) Stream(ctx context.Context, req *user.StreamingRequest, stream user.<span style="color: rgba(0, 0, 0, 1)">User_StreamStream) error {
</span><span style="color: rgba(0, 128, 128, 1)">23</span>   <span style="color: rgba(0, 128, 128, 1)">log</span>.Logf("Received User.Stream request with count: %d", req.<span style="color: rgba(0, 128, 128, 1)">Count</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">24</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)">25</span>   <span style="color: rgba(0, 0, 255, 1)">for</span> i := 0; i &lt; int(req.<span style="color: rgba(0, 128, 128, 1)">Count</span>); i++<span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">26</span>         <span style="color: rgba(0, 128, 128, 1)">log</span>.Logf("Responding: %d",<span style="color: rgba(0, 0, 0, 1)"> i)
</span><span style="color: rgba(0, 128, 128, 1)">27</span>         <span style="color: rgba(0, 0, 255, 1)">if</span> err := stream.Send(&amp;user.<span style="color: rgba(0, 0, 0, 1)">StreamingResponse{
</span><span style="color: rgba(0, 128, 128, 1)">28</span>             <span style="color: rgba(0, 128, 128, 1)">Count</span>: int64(i),
<span style="color: rgba(0, 128, 128, 1)">29</span>         }); err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
</span><span style="color: rgba(0, 128, 128, 1)">30</span>             <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> err
</span><span style="color: rgba(0, 128, 128, 1)">31</span> <span style="color: rgba(0, 0, 0, 1)">      }
</span><span style="color: rgba(0, 128, 128, 1)">32</span> <span style="color: rgba(0, 0, 0, 1)">    }
</span><span style="color: rgba(0, 128, 128, 1)">33</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)">34</span>   <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> nil
</span><span style="color: rgba(0, 128, 128, 1)">35</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">36</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)">37</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> PingPong is a bidirectional stream handler called via client.Stream or the generated client code</span>
<span style="color: rgba(0, 128, 128, 1)">38</span> func (e *User) PingPong(ctx context.Context, stream user.<span style="color: rgba(0, 0, 0, 1)">User_PingPongStream) error {
</span><span style="color: rgba(0, 128, 128, 1)">39</span>   <span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">40</span>         req, err := stream.<span style="color: rgba(0, 0, 0, 1)">Recv()
</span><span style="color: rgba(0, 128, 128, 1)">41</span>         <span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
</span><span style="color: rgba(0, 128, 128, 1)">42</span>             <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> err
</span><span style="color: rgba(0, 128, 128, 1)">43</span> <span style="color: rgba(0, 0, 0, 1)">      }
</span><span style="color: rgba(0, 128, 128, 1)">44</span>         <span style="color: rgba(0, 128, 128, 1)">log</span>.Logf("Got ping %v", req.<span style="color: rgba(0, 0, 0, 1)">Stroke)
</span><span style="color: rgba(0, 128, 128, 1)">45</span>         <span style="color: rgba(0, 0, 255, 1)">if</span> err := stream.Send(&amp;user.Pong{Stroke: req.Stroke}); err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
</span><span style="color: rgba(0, 128, 128, 1)">46</span>             <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> err
</span><span style="color: rgba(0, 128, 128, 1)">47</span> <span style="color: rgba(0, 0, 0, 1)">      }
</span><span style="color: rgba(0, 128, 128, 1)">48</span> <span style="color: rgba(0, 0, 0, 1)">    }
</span><span style="color: rgba(0, 128, 128, 1)">49</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">50</span></pre>
</div>
<p>&nbsp;</p>
</div>
<p>最后修改我们的main.go文件,服务发现使用时consul。</p>
<div class="highlight">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 0, 0, 1)">func main() {
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span>   <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">initCfg()
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 128, 0, 1)">    // New Service</span>
<span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span>   micReg := consul.<span style="color: rgba(0, 0, 0, 1)">NewRegistry()
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span>   service := micro.<span style="color: rgba(0, 0, 0, 1)">NewService(
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span>         micro.Server(s.NewServer()),
<span style="color: rgba(0, 128, 128, 1)"> 9</span>         micro.Name("go.micro.srv.user"),
<span style="color: rgba(0, 128, 128, 1)">10</span>         micro.Version("latest"),
<span style="color: rgba(0, 128, 128, 1)">11</span>         micro.Registry(micReg),
<span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)">    )
</span><span style="color: rgba(0, 128, 128, 1)">13</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)">14</span>   <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Initialise service</span>
<span style="color: rgba(0, 128, 128, 1)">15</span>   service.<span style="color: rgba(0, 0, 0, 1)">Init()
</span><span style="color: rgba(0, 128, 128, 1)">16</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)">17</span>   <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Run service</span>
<span style="color: rgba(0, 128, 128, 1)">18</span>   <span style="color: rgba(0, 0, 255, 1)">if</span> err := service.Run(); err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
</span><span style="color: rgba(0, 128, 128, 1)">19</span>         <span style="color: rgba(0, 128, 128, 1)">log</span>.<span style="color: rgba(0, 0, 0, 1)">Fatal(err)
</span><span style="color: rgba(0, 128, 128, 1)">20</span> <span style="color: rgba(0, 0, 0, 1)">    }
</span><span style="color: rgba(0, 128, 128, 1)">21</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">22</span></pre>
</div>
<p>&nbsp;</p>
</div>
<p>我们使用consul做微服务发现,当然首先你需要安装consul</p>
<div class="highlight">
<div class="cnblogs_code">
<pre>wget https:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">releases.hashicorp.com/consul/1.2.0/consul_1.6.1_linux_amd64.zip</span>
unzip consul_1.6.1_linux_amd64.<span style="color: rgba(0, 0, 0, 1)">zip
mv consul </span>/usr/local/bin/</pre>
</div>
<p>&nbsp;</p>
</div>
<p>启动consul的时候由于在是本地虚拟机上面,所以我们可以简单处理</p>
<div class="highlight">
<div class="cnblogs_code">
<pre>consul agent -dev-client 0.0.0.0 -ui</pre>
</div>
<p>&nbsp;</p>
</div>
<p>这时候可以启动consul的ui了,我本地vagrant的虚拟机192.168.10.100,那么我们打开的是<span class="invisible">http://<span class="visible">192.168.10.100:8500/ui/<span class="invisible">dc1/services</span></span></span></p>
<p>启动user-srv的服务发现consul里面出现 go.micro.srv.user 的服务注册信息了</p>
<p>下面来写hyperf的代码了。按照官方文档安装框架,安装的时候rpc需要选择grpc,需要注意的是你的系统上面需要安装php7.2以上的版本,swoole版本也需要4.3的版本以上,我用的是最新homestead,所以相对而言安装这些依赖比较简单,所以在此强烈推荐。</p>
<p>第一次启动时候官方会要求修改一些php.ini的参数,大家安装要求走就是了。</p>
<p>这部分的流程自己参照官方文档,至于一些扩展的安装可以谷歌或者百度。</p>
<p>安装好框架之后再根目录下面新建一个grpc和proto的目录,把go-micro里面user.proto文件复制到hyperf项目的proto的目录之下。然后在目录下执行命令</p>
<div class="highlight">
<div class="cnblogs_code">
<pre>protoc --php_out=plugins=grpc:../grpc user.proto</pre>
</div>
<p>&nbsp;</p>
</div>
<p>执行成功之后会发现在grpc目录下多出两个文件夹。</p>
<p>接下来我们开始编写client的代码,在hyperf项目的app目录下新建一个Grpc的目录并且新建一个UserClient.php的文件</p>
<div class="highlight">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 0, 0, 1)">namespace App\Grpc;
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 0, 255, 1)">use</span><span style="color: rgba(0, 0, 0, 1)"> Go\Micro\Srv\User\RegisterRequest;
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 0, 255, 1)">use</span><span style="color: rgba(0, 0, 0, 1)"> Go\Micro\Srv\User\UserInfo;
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 255, 1)">use</span><span style="color: rgba(0, 0, 0, 1)"> Hyperf\GrpcClient\BaseClient;
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 255, 1)">class</span> UserClient <span style="color: rgba(0, 0, 255, 1)">extends</span><span style="color: rgba(0, 0, 0, 1)"> BaseClient
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">10</span>   <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span> Register(RegisterRequest <span style="color: rgba(128, 0, 128, 1)">$argument</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 0, 1)">    {
</span><span style="color: rgba(0, 128, 128, 1)">12</span>         <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 128, 1)">$this</span>-&gt;<span style="color: rgba(0, 0, 0, 1)">simpleRequest(
</span><span style="color: rgba(0, 128, 128, 1)">13</span>             '/user.User/Register',
<span style="color: rgba(0, 128, 128, 1)">14</span>             <span style="color: rgba(128, 0, 128, 1)">$argument</span>,
<span style="color: rgba(0, 128, 128, 1)">15</span>            
</span><span style="color: rgba(0, 128, 128, 1)">16</span> <span style="color: rgba(0, 0, 0, 1)">      );
</span><span style="color: rgba(0, 128, 128, 1)">17</span> <span style="color: rgba(0, 0, 0, 1)">    }
</span><span style="color: rgba(0, 128, 128, 1)">18</span> ​</pre>
</div>
<p>&nbsp;</p>
</div>
<p>关于这一块的代码,其实官方文档写得特别详细,具体可以参照官方文档。</p>
<p>新建一个路由</p>
<div class="highlight">
<div class="cnblogs_code">
<pre>Router::addRoute(['GET', 'POST', 'HEAD'], '/grpc', 'App\Controller\IndexController@grpc');</pre>
</div>
</div>
<p>编写控制器</p>
<div class="highlight">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> grpc ()
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span>         <span style="color: rgba(128, 0, 128, 1)">$client</span> = <span style="color: rgba(0, 0, 255, 1)">new</span> \App\Grpc\UserClient('127.0.0.1:9527',<span style="color: rgba(0, 0, 0, 1)"> [
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span>             'credentials' =&gt; <span style="color: rgba(0, 0, 255, 1)">null</span>,
<span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 0, 1)">      ]);
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span>         <span style="color: rgba(128, 0, 128, 1)">$request</span> = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> RegisterRequest();
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span>         <span style="color: rgba(128, 0, 128, 1)">$request</span>-&gt;setEmail("741001560@qq.com"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">10</span>         <span style="color: rgba(128, 0, 128, 1)">$request</span>-&gt;setUsername("chensi"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">11</span>         <span style="color: rgba(128, 0, 128, 1)">$request</span>-&gt;setPassword("123456"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)">13</span>         <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
</span><span style="color: rgba(0, 128, 128, 1)">14</span> <span style="color: rgba(0, 128, 0, 1)">         * @var \Grpc\HiReply $reply
</span><span style="color: rgba(0, 128, 128, 1)">15</span>          <span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 128, 1)">16</span>         <span style="color: rgba(0, 0, 255, 1)">list</span>(<span style="color: rgba(128, 0, 128, 1)">$reply</span>, <span style="color: rgba(128, 0, 128, 1)">$status</span>) = <span style="color: rgba(128, 0, 128, 1)">$client</span>-&gt;Register(<span style="color: rgba(128, 0, 128, 1)">$request</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">17</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)">18</span>         <span style="color: rgba(128, 0, 128, 1)">$message</span> = <span style="color: rgba(128, 0, 128, 1)">$reply</span>-&gt;<span style="color: rgba(0, 0, 0, 1)">getId();
</span><span style="color: rgba(0, 128, 128, 1)">19</span>         <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> [
</span><span style="color: rgba(0, 128, 128, 1)">20</span>             'id' =&gt; <span style="color: rgba(128, 0, 128, 1)">$message</span>
<span style="color: rgba(0, 128, 128, 1)">21</span> <span style="color: rgba(0, 0, 0, 1)">      ];
</span><span style="color: rgba(0, 128, 128, 1)">22</span>   }</pre>
</div>
<p>&nbsp;</p>
</div>
<p>这时候还需要吧根目录下的grpc目录加载进来。修改composer.json文件</p>
<div class="cnblogs_code">
<pre><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)"> psr-4 下面新增两个行</span>
"autoload":<span style="color: rgba(0, 0, 0, 1)"> {
      </span>"psr-4":<span style="color: rgba(0, 0, 0, 1)"> {
            </span>"App\\": "app/",
            "GPBMetadata\\": "grpc/GPBMetadata",
            "Go\\": "grpc/Go"<span style="color: rgba(0, 0, 0, 1)">
      }</span>,
      "files":<span style="color: rgba(0, 0, 0, 1)"> []
    }</span></pre>
</div>
<p>&nbsp;</p>
<p>然后执行composer dump-autoload命令。然后启动hyperf项目,打开浏览器输入<span class="invisible">http://<span class="visible">192.168.10.100:9501/grp<span class="invisible">c</span></span></span>回车,这时候我们就能看到结果了。</p>
<p>这时候我们会发现一个问题,那就是consul在client端压根没用到,在代码中我们还是需要指明我们的端口号。然后再看看官方文档其实是支持consul的,那么将代码改造下。</p>
<p>在app下新建一个Register的目录创建一个文件ConsulServices.php,然后开始编写服务发现的代码,安装consul包以后,由于官方提供的consul包没有文档所以需要自己去看源代码。官方在consul提供的api上面做了简单的封装,如KV、Health等,在实例化话的时候需要穿一个客户端过去。下面提供一个简单的实例。</p>
<div class="highlight">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> &lt;?<span style="color: rgba(0, 0, 0, 1)">php
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 0, 255, 1)">declare</span>(strict_types=1<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 0, 0, 1)">namespace App\Register;
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 255, 1)">use</span><span style="color: rgba(0, 0, 0, 1)"> Hyperf\Consul\Health;
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 255, 1)">use</span><span style="color: rgba(0, 0, 0, 1)"> Psr\Container\ContainerInterface;
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 255, 1)">use</span><span style="color: rgba(0, 0, 0, 1)"> Hyperf\Guzzle\ClientFactory;
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> ConsulServices
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)">13</span>   <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(128, 0, 128, 1)">$servers</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">14</span>   <span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(128, 0, 128, 1)">$container</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">15</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)">16</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)">17</span>   <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span> __construct(ContainerInterface <span style="color: rgba(128, 0, 128, 1)">$container</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">18</span> <span style="color: rgba(0, 0, 0, 1)">    {
</span><span style="color: rgba(0, 128, 128, 1)">19</span>         <span style="color: rgba(128, 0, 128, 1)">$this</span>-&gt;container = <span style="color: rgba(128, 0, 128, 1)">$container</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">20</span> <span style="color: rgba(0, 0, 0, 1)">    }
</span><span style="color: rgba(0, 128, 128, 1)">21</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)">22</span>   <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> getServers()
</span><span style="color: rgba(0, 128, 128, 1)">23</span> <span style="color: rgba(0, 0, 0, 1)">    {
</span><span style="color: rgba(0, 128, 128, 1)">24</span>         <span style="color: rgba(128, 0, 128, 1)">$health</span> = <span style="color: rgba(0, 0, 255, 1)">new</span> Health(<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (){
</span><span style="color: rgba(0, 128, 128, 1)">25</span>             <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 128, 1)">$this</span>-&gt;container-&gt;get(ClientFactory::<span style="color: rgba(0, 0, 255, 1)">class</span>)-&gt;<span style="color: rgba(0, 0, 0, 1)">create([
</span><span style="color: rgba(0, 128, 128, 1)">26</span>               'base_uri' =&gt; 'http://127.0.0.1:8500',
<span style="color: rgba(0, 128, 128, 1)">27</span> <span style="color: rgba(0, 0, 0, 1)">            ]);
</span><span style="color: rgba(0, 128, 128, 1)">28</span> <span style="color: rgba(0, 0, 0, 1)">      });
</span><span style="color: rgba(0, 128, 128, 1)">29</span>         <span style="color: rgba(128, 0, 128, 1)">$resp</span> = <span style="color: rgba(128, 0, 128, 1)">$health</span>-&gt;service("go.micro.srv.user"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">30</span>         <span style="color: rgba(128, 0, 128, 1)">$servers</span> = <span style="color: rgba(128, 0, 128, 1)">$resp</span>-&gt;<span style="color: rgba(0, 0, 0, 1)">json();
</span><span style="color: rgba(0, 128, 128, 1)">31</span>         <span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">empty</span>(<span style="color: rgba(128, 0, 128, 1)">$servers</span><span style="color: rgba(0, 0, 0, 1)">)){
</span><span style="color: rgba(0, 128, 128, 1)">32</span>             <span style="color: rgba(128, 0, 128, 1)">$this</span>-&gt;servers =<span style="color: rgba(0, 0, 0, 1)"> [];
</span><span style="color: rgba(0, 128, 128, 1)">33</span> <span style="color: rgba(0, 0, 0, 1)">      }
</span><span style="color: rgba(0, 128, 128, 1)">34</span>         <span style="color: rgba(0, 0, 255, 1)">foreach</span> (<span style="color: rgba(128, 0, 128, 1)">$servers</span> <span style="color: rgba(0, 0, 255, 1)">as</span> <span style="color: rgba(128, 0, 128, 1)">$server</span><span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 128, 128, 1)">35</span>             <span style="color: rgba(128, 0, 128, 1)">$this</span>-&gt;servers[] = <span style="color: rgba(0, 128, 128, 1)">sprintf</span>("%s:%d",<span style="color: rgba(128, 0, 128, 1)">$server</span>['Service']['Address'],<span style="color: rgba(128, 0, 128, 1)">$server</span>['Service']['Port'<span style="color: rgba(0, 0, 0, 1)">]);
</span><span style="color: rgba(0, 128, 128, 1)">36</span> <span style="color: rgba(0, 0, 0, 1)">      }
</span><span style="color: rgba(0, 128, 128, 1)">37</span> <span style="color: rgba(0, 0, 0, 1)">    }
</span><span style="color: rgba(0, 128, 128, 1)">38</span> }</pre>
</div>
<p>&nbsp;</p>
</div>
<p>这时候发现一个问题如果每次请求过来都去请求一次必然给consul造成很大的负荷。既然用到了swoole框架可以在每次swoole启动的时候去请求一次,然后把服务发现的信息存起来。修改配置文件server。</p>
<div class="highlight">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> 'callbacks' =&gt;<span style="color: rgba(0, 0, 0, 1)"> [
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">      SwooleEvent::ON_BEFORE_START =&gt; ,</span>
<span style="color: rgba(0, 128, 128, 1)"> 3</span>         SwooleEvent::ON_BEFORE_START =&gt; [\App\Bootstrap\ServerStartCallback::<span style="color: rgba(0, 0, 255, 1)">class</span>, 'beforeStart'],
<span style="color: rgba(0, 128, 128, 1)"> 4</span>         SwooleEvent::ON_WORKER_START =&gt; ,
<span style="color: rgba(0, 128, 128, 1)"> 5</span>         SwooleEvent::ON_PIPE_MESSAGE =&gt; ,
<span style="color: rgba(0, 128, 128, 1)"> 6</span>   ],
<span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)">可以在ServerStartCallback类里面请求consul进行服务发现 后面拿到参数就好了。
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)">namespace App\Bootstrap;
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 255, 1)">use</span><span style="color: rgba(0, 0, 0, 1)"> App\Register\ConsulServices;
</span><span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)">​
</span><span style="color: rgba(0, 128, 128, 1)">13</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> ServerStartCallback
</span><span style="color: rgba(0, 128, 128, 1)">14</span> <span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">15</span>   <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> beforeStart()
</span><span style="color: rgba(0, 128, 128, 1)">16</span> <span style="color: rgba(0, 0, 0, 1)">    {
</span><span style="color: rgba(0, 128, 128, 1)">17</span>         <span style="color: rgba(128, 0, 128, 1)">$container</span> = \Hyperf\Utils\ApplicationContext::<span style="color: rgba(0, 0, 0, 1)">getContainer();
</span><span style="color: rgba(0, 128, 128, 1)">18</span>         <span style="color: rgba(128, 0, 128, 1)">$container</span>-&gt;get(ConsulServices::<span style="color: rgba(0, 0, 255, 1)">class</span>)-&gt;<span style="color: rgba(0, 0, 0, 1)">getServers();
</span><span style="color: rgba(0, 128, 128, 1)">19</span> <span style="color: rgba(0, 0, 0, 1)">    }
</span><span style="color: rgba(0, 128, 128, 1)">20</span> }</pre>
</div>
<p>&nbsp;</p>
</div>
<p class="ztext-empty-paragraph">&nbsp;</p>
<p>改造一下原来的控制器</p>
<div class="highlight">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> grpc ()
{

      </span><span style="color: rgba(128, 0, 128, 1)">$container</span> = \Hyperf\Utils\ApplicationContext::<span style="color: rgba(0, 0, 0, 1)">getContainer();
      </span><span style="color: rgba(128, 0, 128, 1)">$servers</span> = <span style="color: rgba(128, 0, 128, 1)">$container</span>-&gt;get(ConsulServices::<span style="color: rgba(0, 0, 255, 1)">class</span>)-&gt;<span style="color: rgba(0, 0, 0, 1)">servers;
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">empty</span>(<span style="color: rgba(128, 0, 128, 1)">$servers</span><span style="color: rgba(0, 0, 0, 1)">)) {
            </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> [
                </span>'errCode' =&gt; 1000,
                'msg'   =&gt; '服务不存在',<span style="color: rgba(0, 0, 0, 1)">
            ];
      }
      </span><span style="color: rgba(128, 0, 128, 1)">$key</span> = <span style="color: rgba(0, 128, 128, 1)">array_rand</span>(<span style="color: rgba(128, 0, 128, 1)">$servers</span>,1); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 哈哈哈一个简单的负载均衡</span>
      <span style="color: rgba(128, 0, 128, 1)">$hostname</span> = <span style="color: rgba(128, 0, 128, 1)">$servers</span>[<span style="color: rgba(128, 0, 128, 1)">$key</span><span style="color: rgba(0, 0, 0, 1)">];
      </span><span style="color: rgba(128, 0, 128, 1)">$client</span> = <span style="color: rgba(0, 0, 255, 1)">new</span> \App\Grpc\UserClient(<span style="color: rgba(128, 0, 128, 1)">$hostname</span>,<span style="color: rgba(0, 0, 0, 1)"> [
            </span>'credentials' =&gt; <span style="color: rgba(0, 0, 255, 1)">null</span>,<span style="color: rgba(0, 0, 0, 1)">
      ]);
      </span><span style="color: rgba(128, 0, 128, 1)">$request</span> = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> RegisterRequest();
      </span><span style="color: rgba(128, 0, 128, 1)">$request</span>-&gt;setEmail("741001560@qq.com"<span style="color: rgba(0, 0, 0, 1)">);
      </span><span style="color: rgba(128, 0, 128, 1)">$request</span>-&gt;setUsername("chensi"<span style="color: rgba(0, 0, 0, 1)">);
      </span><span style="color: rgba(128, 0, 128, 1)">$request</span>-&gt;setPassword("123456"<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)">*
         * @var \Grpc\HiReply $reply
         </span><span style="color: rgba(0, 128, 0, 1)">*/</span>
      <span style="color: rgba(0, 0, 255, 1)">list</span>(<span style="color: rgba(128, 0, 128, 1)">$reply</span>, <span style="color: rgba(128, 0, 128, 1)">$status</span>) = <span style="color: rgba(128, 0, 128, 1)">$client</span>-&gt;Register(<span style="color: rgba(128, 0, 128, 1)">$request</span><span style="color: rgba(0, 0, 0, 1)">);

      </span><span style="color: rgba(128, 0, 128, 1)">$message</span> = <span style="color: rgba(128, 0, 128, 1)">$reply</span>-&gt;<span style="color: rgba(0, 0, 0, 1)">getId();
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> [
            </span>'id' =&gt; <span style="color: rgba(128, 0, 128, 1)">$message</span><span style="color: rgba(0, 0, 0, 1)">
      ];
    }</span></pre>
</div>
<p>&nbsp;</p>
</div>
<p>重启服务,这时候然后刷新浏览器试试。这时候一个简单基于go rpc server和php client的微服务就搭建完成了。当然了这时候还没有心跳机制,hyperf官网提供了一个定时器的功能,我们定时去刷服务发现就好了。</p>
</div><br><br>
来源:https://www.cnblogs.com/a609251438/p/11811761.html
頁: [1]
查看完整版本: go-micro+php+consul简单的微服实现