由於我最近在研究 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 開發調試為一體的集成環境就打造好了,小伙伴們可以快樂的閱讀源碼了。