![](https://s1.ax1x.com/2020/03/14/8l7qSA.png)
> 本文作者:Che Dan
>
> 原文链接:<https://medium.com/@dche423/micro-in-action-call-service-cn-5ac679194636>
本文是[Micro](https://micro.mu/)系列文章的第三篇。我们将以实际开发微服务为主线,顺带解析相关功能。从最基本的话题开始,逐步转到高级特性。
今天将讨论如何调用服务。
---
在前面文章中我们创建并运行了一个服务, 接下来就可以调用它了。
最简单的方式是利用`micro`这个多功能的命令行工具。
## 使用 micro 命令行工具调用服务
首先用`list`子命令列出可用服务:
```bash
$ micro list servicescom.foo.srv.hello
go.micro.http.broker
```
其中`com.foo.srv.hello` 是我们的目标服务,而 `go.micro.http.broker` 是 message broker 的默认实现,这里暂不作展开讨论。
调用前可以先用`get`子命令查看这个服务的详细情况,其中包含了服务版本、接口定义、运行节点等信息:
```bash
$ micro get service com.foo.srv.hello
service com.foo.srv.helloversion latestID Address Metadata
com.foo.srv.hello-7c5ef5ef-22d5-4a10-a5c9-1408d16562f9 10.0.1.6:56004 broker=http,protocol=mucp,registry=mdns,server=mucp,transport=httpEndpoint: Hello.CallRequest: {
name string
}Response: {
msg string
}...
```
然后用`call`子命令发起调用:
```bash
$ micro call com.foo.srv.hello Hello.Call '{"name": "Bill"}'
{
"msg": "Hello Bill"
}
```
我们以 JSON 形式构建了请求(需要使用单引号转义), 并得到了期望的响应。
除上述形式, micro 也支持交互模式。
## 使用 `micro cli` 对服务进行交互式访问
进入交互模式很容易:
```bash
$ micro cli
micro>
```
调用`cli`子命令后, micro 将进入交互模式。
注: 交互模式与非交互模式的命令不完全相同。 前者的命令更简洁。 例如,交互模式下列出所有服务的命令为`list`而不是`list services`。 究其原因, 是因为非交互模式下需要支持更丰富的语义(例如,可以用`list nodes`, 列出所有网络中的节点)。 个人认为这个设计不好, 带来一些概念上的不一致,不利于理解。
```bash
$ micro cli
micro> list
com.foo.srv.hello
go.micro.http.brokermicro>
micro> get com.foo.srv.hello
service com.foo.srv.helloversion latestID Address Metadata
com.foo.srv.hello-7c5ef5ef-22d5-4a10-a5c9-1408d16562f9
...
micro>
micro> call com.foo.srv.hello Hello.Call {"name": "Bill2"}
{
"msg": "Hello Bill2"
}
micro>
```
注意,在交互模式下构建清求时无需单引号转义。
除了`micro cli`以外, 也可以通过浏览器访问交互命令工具。 先在本机运行 `micro web` ,然后访问用浏览器访问 http://127.0.0.1:8082/terminal , 将得到一个功能相似的交互环境:
![micro web, terminal](https://s1.ax1x.com/2020/03/14/8lHpFg.png "micro web, terminal")
**注**:虽然此界面试图提供与`micro cli` 相同的功能。 但实际情况是, 至少在 v1.18.0 它的实现并不完整,且没有得到完备的测试。并且在 micro v2.0.0 后布后,此功能已被从 master 分支中移除。 **因此,不要使用此功能,避免浪费时间**。
## 使用 micro web 客户端调用服务
Micro 也提供的网页客户端,允许用户在浏览器中调用服务。
运行`micro web`以后, 访问 http://127.0.0.1:8082/client 地址将看到如下界面。
选择服务和 Endpoint 后输入请求内容,就可以通过“Execute”按钮调用服务了, 右侧区域以 JSON 格式显示了响应内容。
![micro web, client](https://s1.ax1x.com/2020/03/14/8lHFln.png "micro web, client")
## 用代码调用服务
前面谈到几种方式只是方便了运行时调试。 micro 服务真正的调用者, 还是代码。
下面我们创建一个客户端项目, 其结构如下:
```bash
.
├── main.go
├── plugin.go
├── proto/hello
│ └── hello.proto
│ └── hello.pb.go
│ └── hello.pb.micro.go
├── go.mod
├── go.sum
```
其中除了**main.go** 内容有所不同以外,其它文件的内容与含义均与[上篇文章](https://medium.com/@dche423/micro-in-action-part2-cn-9bbc33d356eb)所描述的一致,此处不再赘述。 **main.go** 中代码如下:
```go
package main
import (
"context"
"fmt"
"github.com/micro/go-micro"
hello "hello/proto/hello"
)
func main() {
// New Service
service := micro.NewService(
micro.Name("com.foo.srv.hello.client"), //name the client service
)
// Initialise service
service.Init()
//create hello service client
helloClient := hello.NewHelloService("", service.Client())
//invoke hello service method
resp, err := helloClient.Call(context.TODO(), &hello.Request{Name: "Bill 4"})
if err != nil {
fmt.Println(err)
return
}
fmt.Println(resp.Msg)
}
```
- 首先创建并初始化 micro.Service 实例, 将其命名为 com.foo.srv.hello.client。这个名字并没有特殊意义,在真实项目中很可能完全不同。
- 然后创建 HelloSevice 的客户端实例, 注意我们为 `hello.NewHelloService`方法传入的第一个参数是空字符串, 这是 micro 的一项约定。 如果不指定服务名称, 那么客户端将使用服务的默认名(即 **com.foo.srv.hello**)进行查找和调用。方法的第二个参数是从 service 实例中取得的 `github.com/micro/go-micro/client.Client` 实例。
- 接下来就是调用服务方法了。先传入`context.Context`实例 , 此处选择`context.TODO()`作了简化处理,在真实项目中你需要传入实际的 Context;然后传入入请求内容。
准备好代码以后即可编译运行:
```bash
$ go run main.go plugin.go
Hello Bill 4
$
```
将看到期望的响应结果。
如果此时服务并没有运行, 则会报出错误:
```bash
$ go run main.go plugin.go
{"id":"go.micro.client","code":500,"detail":"service com.foo.srv.hello: not found","status":"Internal Server Error"}
$
```
至此, 大功告成。
---
## 总结
本文讨论了如何调用一个已经存在服务。
micro 提供了丰富的工具, 可以用来在运行时查看服务状态及调用服务方法。 这其中既有命令行工具, 也有基于 web 界面工具。
最后,我们创建了一个客户端项目,用代码真正完成了服务的调用。
有疑问加站长微信联系(非本文作者))