我想将AWS X-Ray应用于Java批处理
AWS X-Ray 是什么?
-
- APM(Application Performance Monitor)
- https://docs.aws.amazon.com/ja_jp/xray/latest/devguide/aws-xray.html
X射线的特点
-
- managed service
-
- 従量料金(永久無料枠あり)
-
- agent(デーモン) はトレース情報の送信のみ
-
- トレース情報を作るのはApplicationに埋め込むSDK
ソース修正・ビルドが必要
X光的使用场景
-
- 商用APMのライセンス体系の隙間
マイクロサービス(有償agentフィーが…)
Serverless(agent入れようがない)
多数のバッチ処理
開発環境(開発初期こそAPMが欲しい → 無料枠で)
将其应用于Java批处理
-
- SampleはほとんどWeb Application
- HTTP Requestをトレースするのは SDK入れてimport文を差し替えるだけ
这本书只强调了主要内容的介绍,即使搜索也找不到合适的应用例子…
非同步的簡單事件呼叫、三層網頁應用程式、由數千個服務構成的複雜微服務應用程式等。
可以尝试使用「非同步的简单事件调用」
精湛的空挥
只需要安装SDK,AWS API CALL就会被追踪吗?
可能会在AWS控制台上显示出来吗?
-
- 对已有的Java批处理程序添加xray SDK依赖关系(在Maven的pom.xml文件中)
-
- 进行构建和开发部署
- 执行任务
没发生任何事情
X光恶魔
-
- UDP ポート 2000 のトラフィックをリッスン
- AWS X-Ray API に中継する
# curl .../xray-daemon/aws-xray-daemon-2.x.rpm -o xray.rpm
# yum install -y xray.rpm
AWS X-Ray控制台完全不动。
以下有关”デーモンログ”的中文翻译选项:
– 恶魔日志
– 魔鬼记录
– 妖魔日志
– 魔王纪录
– 鬼神日志
# ps ax | grep xray
13910 ? Ssl 0:01 xray -f /var/log/xray/xray.log
# cat /var/log/xray/xray.log
2019-07-09T17:13:11+09:00 [Info] Initializing AWS X-Ray daemon 2.1.3
2019-07-09T17:13:11+09:00 [Info] Using buffer memory limit of 78 MB
2019-07-09T17:13:11+09:00 [Info] 1248 segment buffers allocated
2019-07-09T17:13:11+09:00 [Info] Using region: ap-northeast-1
看起来终端正常。似乎没有收到任何来自2000端口的东西。
X光的你好世界
# sh xray_start.sh
# tail /var/log/xray/xray.log
019-07-10T11:01:11+09:00 [Error] Sending segment batch failed with: AccessDeniedException:
User: arn:aws:sts::...:assumed-role/...-role/i-...
is not authorized to perform: xray:PutTraceSegments
AWS操作的常见问题:“叹气。又要添加权限了…”
添加后,在X-Ray控制台的迹象下发现了1个!
TraceId是什么?
只需要一個選項
只有在SDK中生成,或者開始於包含TraceID的SQS的範例,已經開始閱讀了xray_start.sh。
START_TIME=$(date +%s)
HEX_TIME=$(printf '%x\n' $START_TIME)
GUID=$(dd if=/dev/random bs=12 count=1 2>/dev/null | od -An -tx1 | tr -d ' \t\n')
TRACE_ID="1-$HEX_TIME-$GUID"
1-” + Epoch Time 的 Hex表示 + “-” + GUID
任何人都可以生成的ID系统:独一无二和大致按时间顺序排列是要求
在Java批处理中进行追加操作
import com.amazonaws.xray.AWSXRayRecorder;
import com.amazonaws.xray.AWSXRayRecorderBuilder;
import com.amazonaws.xray.entities.TraceID;
import com.amazonaws.xray.plugins.EC2Plugin;
...
private static AWSXRayRecorder xRayRecorder = AWSXRayRecorderBuilder.standard().withPlugin(new EC2Plugin()).build();
private static final TraceID traceId = new TraceID();
...
xRayRecorder.beginSegment(traceId.toString());
...
xRayRecorder.endSegment();
...
参考示例:https://github.com/aws-samples/aws-xray-apache-kafka-sample
Java追加记录概述
-
- 导入import库
-
- 构建AWSXRayRecorder
-
- 生成TraceID
- 使用AWSXRayRecorder.beginSegment(), endSegment()包裹处理代码。
已出发
[root@gin-mng-za-1 ~]# tail /var/log/xray/xray.log
...
2019-07-11T09:26:29+09:00 [Info] Successfully sent batch of 1 segments (0.086 seconds)
{
"Duration": 42.792,
"Id": "1-5d26820a-5249372acaaa8b1b875a72e5",
"Segments": [
{
"Document": {
"id": "6626990748dee123",
"name": "1-5d26820a-83c2abc49e5ca6595e9f9dbd",
"start_time": 1562804746.446,
"end_time": 1562804789.238,
"aws": {
"ec2": {
"availability_zone": "ap-northeast-1a",
"instance_id": "i-..."
},
"xray": {
"sdk_version": "2.2.0",
"sdk": "X-Ray for Java"
}
},
"service": {
"runtime": "Java HotSpot(TM) 64-Bit Server VM",
"runtime_version": "1.8.0_..."
},
"trace_id": "1-5d26820a-5249372acaaa8b1b875a72e5",
"origin": "AWS::EC2::Instance"
},
"Id": "6626990748dee123"
}
]
}
JDBC拦截器
只需要将xray SDK添加到依赖库中,然后在jdbc.properties文件中添加一行内容。
dataSource.jdbcInterceptors=com.amazonaws.xray.sql.postgres.TracingInterceptor
subsegments 被一起进行了PUT操作
"subsegments": [
{
"id": "23894958bbe2a6a0",
"name": "s....@db.....rds",
"start_time": 1562824789.49,
"end_time": 1562824789.532,
"sql": {
"url": "jdbc:postgresql://db....rds:.../s...",
"database_type": "PostgreSQL",
"database_version": "9.....",
"driver_version": "...",
"user": "...",
"preparation": "statement"
},
"namespace": "remote"
}
]
HTTP 服务呼叫
在源代码上将 Apache HttpClient 替换为 com.amazonaws.xray.proxies 的兼容类。
只需替换字面上的文字,逻辑仍然保持不变,不是吗?
import com.amazonaws.xray.proxies.apache.http.HttpClientBuilder;
...
CloseableHttpClient httpclient = HttpClientBuilder.create().build(); //変更なし
只需这样,HttpClient通过API可能会被添加为子段落
源代码更改总结
-
- 在pom.xml中添加xray SDK,
-
- 在main函数中添加import语句,
-
- 构建AWSXRayRecorder,
-
- 生成TraceID,
-
- 使用AWSXRayRecorder.beginSegment()和endSegment()包装处理,
-
- 在jdbc.properties中添加拦截器设置,
- 将HttpClient的import语句替换为xray SDK的类。
基础设施变更总结
-
- 在目标实例上安装X-Ray守护程序
-
- 在目标实例配置文件上授予X-Ray:PutTraceSegments等权限
参考:AWS管理策略AWSXRayDaemonWriteAccess
成本估算
-
- 5分, 10分, 15分, 30分周期の job各1本
-
- その他1日1回のjob数本
-
- 合計 585 jobs/day = 18K/mo
- X-Rayの永久無料枠は 100K/mo ずっと無料
只要进行临时查询,虽然有查询方面的费用,但在免费范围内。
碎片
-
- SQL本文がまだ出せてない
-
- HTTP送信のsubsegment出力 未検証
調査対象バッチの Apache HttpClient 3.x でSDK replaceできなかった
httpclient3.x系から4.5まで上げたら大変だった…
役に立つ分析が可能なのか 未実証