Zipkin

zipkin为分布式链路调用监控系统,聚合各业务系统调用延迟数据,达到链路调用监控跟踪。

安装

1
docker run --name zipkin -d -p 9411:9411 openzipkin/zipkin

RPC协议接入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
namespace App\Common\Zipkin;


use Xin\Thrift\ZipkinService\Options;

use Xin\Traits\Common\InstanceTrait;

use Exception;

use Zipkin\Propagation\TraceContext;


class ZipkinClient

{

use InstanceTrait;


public $context;


public $options;


public function __construct()

{

// if (defined('IS_MEMORY_RESIDENT') && IS_MEMORY_RESIDENT === true) {

// throw new Exception('常驻内存模式下,不允许使用单例对象作为调用链存储方式');

// }

}


public function setOptions(Options $options)

{

$context = TraceContext::create(

$options->traceId,

$options->spanId,

$options->parentSpanId,

$options->sampled

);


$this->context = $context;

$this->options = $options;

}


public function getOptions()

{

return $this->options;

}


public function getContext()

{

return $this->context;

}

}

客户端实现__call方法如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public function __call($name, $arguments)
{

$options = end($arguments);

if (!$options instanceof Options) {

$options = ZipkinClient::getInstance()->getOptions();

$arguments[] = $options;

}

return $this->client->$name(...$arguments);

}

服务端实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
namespace App\Thrift\Services;


use App\Common\Zipkin\ZipkinClient;

use App\Core\Zipkin\Tracer;

use App\Thrift\Services\Impl\ImplHandler;

use Phalcon\Di\Injectable;

use Xin\Thrift\ZipkinService\ThriftException;

use Zipkin\Tracing;


abstract class Handler extends Injectable

{

/** @var ImplHandler */

protected $impl;


public function __call($name, $arguments)

{

if (empty($this->impl)) {

throw new ThriftException([

'code' => 0,

'message' => '微服务Handler没有设置其实现'

]);

}


/** @var Tracer $tracing */

$tracer = di('tracer');


$spanName = $this->impl . '@' . $name;

$options = array_pop($arguments);

list($child_trace, $options) = Tracer::getInstance()->newChild($tracer, $spanName, $options);

ZipkinClient::getInstance()->setOptions($options);

$arguments[] = $options;


try {

$result = $this->impl::getInstance()->$name(...$arguments);

} finally {

$child_trace->finish();

$tracer->flush();

}


return $result;

}

}

项目地址

zipkin