由于我最近在研究 envoy 这个项目,这是个cpp的项目,对于我这种cpp新人来说还是比较有压力的,感觉处处都是坑,开个引导文章记录一下。
如果要研究 envoy 项目源码,那肯定是需要代码跳转的,但是如果用 clion 打开,那么你会发现 envoy 是用bazel 构建的,没有CMakeLists.txt无法跳转,bazel-cmakelists 这个工具也已经几年都没迭代了,根本用不了。所以按照官方推荐的使用 vscode 来进行构建开发。
在 envoy 这个项目里面,由于运行环境是基于ubuntu的docker环境跑的,所以提供了vscode container 这种模式给我们开发者进行开发调试。
看了一下 envoy 的开发文档,感觉貌似使用起来是很简单的,但是有些地方踩坑也让我浪费了不少时间。
开发环境的构建#
创建 dev container环境#
首先,我们需要在我们的机器上安装好 docker desktop,然后用vscode打开我们的envoy项目,打开 envoy/.devcontainer/devcontainer.json 文件,这个时候 vscode 会弹出如下提示:
然后我们点击 Reopen in Container 即可加载构建 vscode Container 开发环境。但是有些小伙伴说,不小心把这个提示关了,怎么手动打开呢?
在mac里我们可以按下:command+shift+p
,然后输入 reopen:
生成相应的依赖文件#
然后进入到容器内部之后,需要 Refresh Compilation Database
,也就是运行 tools/vscode/refresh_compdb.sh
脚本,这个脚本会帮我们生成代码完成的所有依赖项,例如 protobuf 生成的代码、外部依赖项。
但是直接运行的话,会报错:
然后我去看官方文档VSCode Remote - Containers,文档里面和我说一般需要把devcontainer.json
的里面的 remoteUser 设置为 root, 然后我又重新构建了几次,都是直接卡死,原因不明。
然后我跑到宿主机给 vscode 这个用户加权限,结果是找不到这个用户。后面我幡然醒悟,这个权限命令应该在容器内部执行才可以:
# 这个命令需要在容器内部执行
sudo chown -R vscode /workspaces
然后再运行 tools/vscode/refresh_compdb.sh
脚本 ,ok了,没有报错。然后检查生成的 complie_commands.json文件也没有问题。
我们再检查一下代码可以正常跳转,并且没有报错了。
开发环境进行envoy调试#
当然,除了让我们的开发环境的代码能够跳转其实还不够,最好是可以进行代码的调试,下面我们就看看怎么调试 envoy。
配置一个demo yaml#
在代码的 config 下面其实有很多 yaml 模板,可以随便拿一个出来放到envoy根目录下面,我这里也给一个 yaml 例子:
admin:
access_log_path: /tmp/admin_access.log
address:
socket_address:
protocol: TCP
address: 0.0.0.0
port_value: 9901
static_resources:
listeners:
- name: listener_0
address:
socket_address:
protocol: TCP
address: 0.0.0.0
port_value: 10001
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
scheme_header_transformation:
scheme_to_overwrite: https
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match:
prefix: "/"
route:
host_rewrite_literal: www.envoyproxy.io
cluster: service_envoyproxy_io
http_filters:
- name: envoy.filters.http.router
clusters:
- name: service_envoyproxy_io
connect_timeout: 30s
type: LOGICAL_DNS
# Comment out the following line to test on v6 networks
dns_lookup_family: V4_ONLY
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: service_envoyproxy_io
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: www.envoyproxy.io
port_value: 443
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
sni: www.envoyproxy.io
生成 vscode 调试文件#
在根目录下运行下面命令:
tools/vscode/generate_debug_config.py //source/exe:envoy-static --args "-c envoy.yaml"
上面 --args 参数里面填的就是我们上面的 yaml 文件,这个编译等待的过程是十分漫长的,我 8C16G 的机器差不多花了我1个小时才弄好。
运行好之后,可以看到帮我们生成好了 launch.json 文件:
调试#
然后我们按 F5 发现可以进入到我们的 mian 函数的断点中,没有什么问题:
到此为止,我们的 envoy 开发调试为一体的集成环境就打造好了,小伙伴们可以快乐的阅读源码了。