Golang Go语言 OPA 进阶-测试、性能分析和基准测试
Golang Go语言 OPA 进阶-测试、性能分析和基准测试
本文来讲讲OPA
的测试(test
)、性能分析(profile
)和(benchmark
)
掌握他们,对于保证策略代码的质量和决策效率有很大的帮助
test
OPA
的测试很简单。
所有test_
前缀的的规则(rule
)都是测试。
Tips: 虽然是测试,但其本质上其仍是规则,仍然可以被查询。 另外建议文件名遵循
_test.rego
后缀加以区分
这里拿quick-start
的测试例子来看下:
package example_rbac_test
import data.example_rbac
test_not_allow {
not example_rbac.allow with input as {}
}
test_allow {
example_rbac.allow with input as {
“action”: {
“operation”: “read”,
“resource”: “widgets”,
},
“subject”: {“user”: “inspector-alice”},
}
}
就这样即覆盖了allow
规则的全部测试用例。
注意这里with
起到了数据模拟的作用(data mocking
)
Tips: 函数不可用
with
替换
对应的命令行是:
cd quick-start
opa test . -v
# 输出如下
data.example_rbac_test.test_not_allow: PASS (693.201µs)
data.example_rbac_test.test_allow: PASS (562.02µs)
--------------------------------------------------------------------------------
PASS: 2/2
也可以查看测试覆盖率:
opa test . -c
设定测试覆盖率标准:
opa test . -c --threshold 100
(这里提示下别忘了vscode-opa
支持可视化覆盖率展示哦)
也支持选择测试用例执行:
opa test -r test_allow . -v
profile
cd quick-start
opa eval --profile -d example.rego -d data.json -i input.json -f pretty "data.example_rbac.allow"
true
±-----------------------------±--------+
| METRIC | VALUE |
±-----------------------------±--------+
| timer_rego_data_parse_ns | 18332 |
| timer_rego_load_files_ns | 5506307 |
| timer_rego_module_compile_ns | 573408 |
| timer_rego_module_parse_ns | 5226456 |
| timer_rego_query_compile_ns | 87390 |
| timer_rego_query_eval_ns | 292198 |
| timer_rego_query_parse_ns | 277932 |
±-----------------------------±--------+
±---------±---------±---------±------------------------+
| TIME | NUM EVAL | NUM REDO | LOCATION |
±---------±---------±---------±------------------------+
| 54.121µs | 1 | 1 | data.example_rbac.allow |
| 42.776µs | 1 | 2 | example.rego:15 |
| 37.861µs | 1 | 1 | example.rego:9 |
| 35.81µs | 1 | 1 | example.rego:25 |
| 22.469µs | 1 | 1 | example.rego:10 |
| 21.353µs | 2 | 2 | example.rego:16 |
| 16.888µs | 2 | 1 | example.rego:17 |
| 15.923µs | 2 | 1 | example.rego:23 |
| 14.736µs | 1 | 2 | example.rego:22 |
| 8.798µs | 1 | 1 | example.rego:24 |
±---------±---------±---------±------------------------+
Tips: --profile 还支持结果排序和限制显示条数
--profile-sort
:对性能分析结果排序,默认按total_time_ns => num_eval => num_redo => file => line
排序, 详见profile-sort 文档--profile-limit
:显示几条分析结果,默认 10 条
benchmark
opa
也支持benchmark
,基本实现了go
的benchmark
的使用方式, 甚至有更详细的结果(毕竟一直标榜性能么)
默认benchmark
会展示内存(--benchmem
)和查询(--metrics
)的基准测试结果
$ opa bench --count 1 -d example.rego -d data.json -i input.json -f pretty "data.example_rbac.allow"
+-------------------------------------------+------------+
| samples | 14162 |
| ns/op | 93655 |
| B/op | 15117 |
| allocs/op | 311 |
| histogram_timer_rego_query_eval_ns_75% | 89900 |
| histogram_timer_rego_query_eval_ns_90% | 112253 |
| histogram_timer_rego_query_eval_ns_95% | 125465 |
| histogram_timer_rego_query_eval_ns_99% | 222404 |
| histogram_timer_rego_query_eval_ns_99.9% | 549291 |
| histogram_timer_rego_query_eval_ns_99.99% | 550611 |
| histogram_timer_rego_query_eval_ns_count | 14162 |
| histogram_timer_rego_query_eval_ns_max | 550611 |
| histogram_timer_rego_query_eval_ns_mean | 76735 |
| histogram_timer_rego_query_eval_ns_median | 68336 |
| histogram_timer_rego_query_eval_ns_min | 38896 |
| histogram_timer_rego_query_eval_ns_stddev | 38828 |
+-------------------------------------------+------------+
当然也集成到了opa test
中
$ opa test -v --bench example.rego example_test.rego data.json
data.example_rbac_test.test_not_allow 15139 74172 ns/op 62044 timer_rego_query_eval_ns/op 14666 B/op 270 allocs/op
data.example_rbac_test.test_allow 10000 102658 ns/op 90779 timer_rego_query_eval_ns/op 17825 B/op 367 allocs/op
--------------------------------------------------------------------------------
PASS: 2/2
而且--format
指定gobench
的话,还支持了benchstat
, 是Go
亲生的,无疑了
opa test -v --bench --count 5 --format gobench example.rego example_test.rego data.json| tee b.txt
BenchmarkDataExampleRbacTestTestNotAllow 15186 87349 ns/op 73644 timer_rego_query_eval_ns/op 14663 B/op 270 allocs/op
BenchmarkDataExampleRbacTestTestAllow 10000 115857 ns/op 101565 timer_rego_query_eval_ns/op 17828 B/op 367 allocs/op
PASS: 2/2
…
benchstat b.txt
name time/op
DataExampleRbacTestTestNotAllow 92.9µs ±40%
DataExampleRbacTestTestAllow 123µs ± 8%
name timer_rego_query_eval_ns/op
DataExampleRbacTestTestNotAllow 79.0k ±41%
DataExampleRbacTestTestAllow 109k ± 9%
name alloc/op
DataExampleRbacTestTestNotAllow 14.7kB ± 0%
DataExampleRbacTestTestAllow 17.8kB ± 0%
name allocs/op
DataExampleRbacTestTestNotAllow 270 ± 0%
DataExampleRbacTestTestAllow 367 ± 0%
基准测试前后对比自然也是支持,如benchstat old.txt new.txt
,就不详述了。
这些工具固然好,高性能还是需要 follow 一些经验法则的
这里引用官方对于性能优化的建议如下(key-takeaways):
- 编写策略(
policy
)要最大程度地减少迭代和搜索。- 使用的数组元素有唯一标识符时,改为唯一标识作为 key 的对象。
- 考虑利用部分评估(partial-evaluation)以将非线性策略编译为线性策略。
- 利用规则索引优化(rule-indexing)编写策略,以便规则索引有效。
- 使用探查器(
profiler
)可帮助确定策略的哪些部分将从提高的性能中受益最大。 - 使用基准测试工具(
benchmark tools
)来帮助获取真实世界的时序数据并检测策略性能变化。
里边提到的
partial-evaluation
和rule-indexing
是保证OPA
高性能的两个重要特性,感兴趣的同学可以自行查看下。
下一篇,我们来谈谈OPA
的一个重磅功能 - bundle
, 一种将策略及数据进行包组织的方式,也支持丰富的管理restful api
,适合分布式决策服务的构建。
文章首发公众号:newbmiao
推荐阅读:OPA 系列
更多关于Golang Go语言 OPA 进阶-测试、性能分析和基准测试的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于Golang Go语言 OPA 进阶-测试、性能分析和基准测试的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
针对您提到的Golang、Go语言以及OPA进阶中的测试、性能分析和基准测试,以下是我的专业回复:
在Golang中,测试是确保代码质量的关键环节。OPA(Open Policy Agent)作为一种策略执行引擎,同样需要进行全面的测试。对于OPA的测试,主要依赖其内置的测试框架,通过定义以“test_”前缀的规则来进行。这些测试规则本质上仍是OPA的策略规则,但可以用于验证其他规则的正确性。
性能分析方面,Golang提供了强大的工具,如pprof,可以帮助开发者深入了解程序的性能瓶颈。对于OPA,虽然其性能分析可能不如Golang原生应用那样直接,但也可以通过类似的方式进行,例如通过模拟大量请求来观察策略执行的效率和响应时间。
基准测试在Golang中通常用于评估函数或代码段的性能。对于OPA,基准测试同样重要,可以帮助开发者了解策略规则在不同负载下的表现。通过运行基准测试,可以获得如每次查询的耗时、内存占用等关键性能指标。
总之,无论是Golang还是OPA,测试、性能分析和基准测试都是确保代码质量和性能的重要手段。建议深入学习相关工具和框架的使用,以更好地优化和提升您的应用程序。