9.6 KiB
Call link tracking
In the microservice architecture, there will be a lot of services by splitting, which means that a business request may go through 3 or 4 services at least, even dozens or more. Under this architecture, it is extremely difficult when we need to debug a certain problem. Then we need a call link tracking system to help us dynamically display the service call link so that we can quickly locate the problem, and also optimize the service based on the link information.
In Hyperf
, we provide the hyperf/tracer component to track and analyze the call of each cross-network request. Currently, the Zipkin system and the Jaeger system are docked according to the OpenTracing protocol. Users can also customize this by following the OpenTracing protocol.
Installation
By Composer
composer require hyperf/tracer
The hyperf/tracer component has installed Zipkin related dependencies by default. If you want to use Jaeger, you need to execute the following command to install the corresponding dependencies:
composer require jonahgeorge/jaeger-client-php
Add component configuration
If the file does not exist, execute the following command to add the config/autoload/opentracing.php
configuration file:
php bin/hyperf.php vendor:publish hyperf/tracer
usage
Config
Enable tracking
By default, it provides monitoring of Guzzle HTTP
calls, Redis
calls, and DB
calls or AOP
aspect processing to achieve the propagation and tracking of the call link. These tracings are not enabled by default. You need to modify enable
items in the config/autoload/opentracing.php
configuration file to enable the tracing of certain remote calls.
<?php
return [
'enable' => [
// enable the tracing of Guzzle HTTP calls
'guzzle' => false,
// enable the tracing of Redis calls
'redis' => false,
// enable the tracing of DB calls
'db' => false,
],
];
Before starting to trace, we need to select the Tracer driver to be used and configure the Tracer.
Select tracker driver
The value corresponding to default
in the configuration file is the name of the used driver. The specific configuration of the driver is defined under the tracer
item, using the same driver as the key
.
<?php
return [
// Select the default Tracer driver, the selected Tracer name corresponds to the key defined under tracers
'default' => env('TRACER_DRIVER', 'staging_zipkin'),
// Other configurations are omitted here in this example
'enable' => [],
'tracer' => [
// Zipkin config
'staging_zipkin' => [
'driver' => \Hyperf\Tracer\Adapter\ZipkinTracerFactory::class,
],
// another Zipkin config
'producton_zipkin' => [
'driver' => \Hyperf\Tracer\Adapter\ZipkinTracerFactory::class,
],
// Jaeger config
'jaeger' => [
'driver' => \Hyperf\Tracer\Adapter\JaegerTracerFactory::class,
],
]
];
Note that as shown in the example configuration, you can configure multiple sets of Zipkin drivers or Jaeger drivers. Although the underlying systems used are the same, their specific configurations can be different. A common scenario is that we want 100% sampling rate in the test environment, but with 1% sampling rate in the production environment, two sets of drivers can be configured, and then different drivers can be selected according to the environment variables under the default
item.
Configure Zipkin
When using Zipkin, add the specific configuration of Zipkin to the tracer
item in the configuration file.
<?php
use Zipkin\Samplers\BinarySampler;
return [
// default Tracer
'default' => env('TRACER_DRIVER', 'zipkin'),
// Other configurations are omitted here in this example
'enable' => [],
'tracer' => [
// Zipkin drive config
'zipkin' => [
// current app config
'app' => [
'name' => env('APP_NAME', 'skeleton'),
// If ipv6 and ipv6 are null, the component will automatically detect from the Server
'ipv4' => '127.0.0.1',
'ipv6' => null,
'port' => 9501,
],
'driver' => \Hyperf\Tracer\Adapter\ZipkinTracerFactory::class,
'options' => [
// the endpoint address of Zipkin service
'endpoint_url' => env('ZIPKIN_ENDPOINT_URL', 'http://localhost:9411/api/v2/spans'),
// Request timeout (in seconds)
'timeout' => env('ZIPKIN_TIMEOUT', 1),
],
// Sampler, track all requests by default
'sampler' => BinarySampler::createAsAlwaysSample(),
],
],
];
Configure Jaeger
When using Jaeger, add the specific configuration of Jaeger to the tracer
item in the configuration file.
<?php
use Hyperf\Tracer\Adapter\JaegerTracerFactory;
use const Jaeger\SAMPLER_TYPE_CONST;
return [
// default Tracer
'default' => env('TRACER_DRIVER', 'jaeger'),
// Other configurations are omitted here in this example
'enable' => [],
'tracer' => [
// Jaeger drive config
'jaeger' => [
'driver' => JaegerTracerFactory::class,
// project name
'name' => env('APP_NAME', 'skeleton'),
'options' => [
// Sampler, track all requests by default
'sampler' => [
'type' => SAMPLER_TYPE_CONST,
'param' => true,
],
// the address which should report to
'local_agent' => [
'reporting_host' => env('JAEGER_REPORTING_HOST', 'localhost'),
'reporting_port' => env('JAEGER_REPORTING_PORT', 5775),
],
],
],
],
];
More configurations about Jaeger can be found in here].
Configure JsonRPC tracking enabling
JsonRPC's link tracking is not in the unified configuration, and temporarily belongs to the Beta
version.
We only need to configure aspects.php
, and add the following Aspect
to enable it.
Tip: Don’t forget to add the corresponding TraceMiddleware on the opposite site.
<?php
return [
Hyperf\Tracer\Aspect\JsonRpcAspect::class,
];
Configure middleware
After configuring the driver, you need to configure the middleware to enable the collection function to collect information.
Open the config/autoload/middlewares.php
file and enable the middleware on the http
node.
<?php
declare(strict_types=1);
return [
'http' => [
\Hyperf\Tracer\Middleware\TraceMiddleware::class,
],
];
Configure Span tag
For some Span Tag names that Hyperf automatically collects tracking information for, you can change the corresponding name by changing the Span Tag configuration. Just add the tags
configuration in the configuration file config/autolaod/opentracing.php
. The reference configuration is as follows. If the configuration item exists, the value of the configuration item shall prevail. If the configuration item does not exist, the default value of the component shall prevail.
return [
'tags' => [
// HTTP client (Guzzle)
'http_client' => [
'http.url' => 'http.url',
'http.method' => 'http.method',
'http.status_code' => 'http.status_code',
],
// Redis client
'redis' => [
'arguments' => 'arguments',
'result' => 'result',
],
// database client (hyperf/database)
'db' => [
'db.query' => 'db.query',
'db.statement' => 'db.statement',
'db.query_time' => 'db.query_time',
],
]
];
Replace the sampler
The default sampler records the call link for all requests, which will have a certain impact on performance, especially memory usage. So we only need to track the call link when we want, then we need to replace the sampler. It's easy to replace the sampler, take the Zipkin as an example, just change the corresponding value of the configuration item opentracing.zipkin.sampler
to your sampler object instance, as long as your sampler object implements the Zipkin\Sampler
interface class.
Access to Alibaba Cloud link tracking service
When we are using Alibaba Cloud’s link tracking service, since the opposite end also supports the Zipkin
protocol, you can directly modify the value of endpoint_url
in the config/autoload/opentracing.php
configuration file to your corresponding address of Aliyun region
. The specific address can be obtained in Alibaba Cloud's link tracking service. For more details, please refer to Alibaba Cloud Link Tracking Service Help Document
Use other Tracer drivers
You can also use any other Tracer drivers which follows the OpenTracing protocol. In the Driver field, fill any class that implements Hyperf\Tracer\Contract\NamedFactoryInterface
. This interface has only one make()
function, the parameter is the driver name, and it needs to return an instance that implements OpenTracing\Tracer.