Ubuntu下编译envoy mobile

前言

Envoy 是一个开源的高性能、可扩展的代理服务,最初由 Lyft 公司开发。它设计用于处理现代的微服务架构中的网络通信,并提供了许多功能,包括负载均衡、服务发现、路由、认证、授权等。Envoy 被广泛用于构建和部署云原生应用程序以及微服务体系结构。

Envoy Mobile 是 Envoy 的移动端版本,专门设计用于在移动应用程序中处理网络流量。
envoy 提供了官方依赖,不过提供的api有限,如果需要对其进行定制则需要重新编译构建aar

1
api("io.envoyproxy.envoymobile:envoy:0.5.0.20231016")

本文将介绍在Linux下编译envoy mobile,生成aar文件的流程。

1 使用环境

硬件要求
  • 内存8G以上,建议12G以上
  • 磁盘空间50G以上,建议使用SSD
  • 科学上网(可访问google、github等网站)
编译环境
  • Ubuntu 22.04.3 LTS Desktop 64-bit
  • Java 8 以上
  • Android SDK Platform 30
  • Android NDK 21
  • Python 3.10.12
  • Bazel 6.3.2
  • c++ 环境

2 搭建环境

2.1 git

1.打开终端,输入以下命令以安装git,下同

1
2
3
4
5
6
# 检查git 是否安装
git --version

# 安装git
sudo apt update
sudo apt install git

2.配置git

1
2
git config --global user.name "youname"
git config --global user.email "[email protected]"

2.2 curl

1
sudo apt install curl

2.3 Java环境

1.检查是否已安装jdk

1
2
3
4
5
# 查看jdk版本号
java -version

# 没有则进行安装
sudo apt-get install openjdk-11-jdk

2.配置环境变量

1
2
3
4
5
6
7
8
# 打开bashrc文件
sudo gedit ~/.bashrc

#在最后一行加上以下内容:
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

2.4 安装Android NDK

1.安装方式有很多,可以从google官网下载Linux平台的ndk包,解压并复制放到Ubuntu指定的ndk目录。也可以通过Android studio进行下载。

https://developer.android.com/ndk/downloads?hl=zh-cn#download

1
2
# 检查ndk是否安装
ndk-build -v

2.下载完成配置ndk环境变量

1
2
3
4
5
sudo gedit ~/.bashrc

export NDK_HOME=/home/xiaochuan/Android/android-ndk-r10b
export PATH=$PATH:$NDK_HOME

2.5 安装 Android Sdk

1.从官网下载sdk包,或者通过Android stdio下载(Ubuntu应用商店支持Android Studo)

1
2
# 检查Android SDK是否安装
adb --version

2.配置环境变量

1
2
# 打开 .bashrc 文件
sudo gedit ~/.bashrc

在末尾增加以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
# jdk环境变量
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
export PATH=$PATH:$JAVA_HOME/bin

# Android sdk环境变量
export ANDROID_HOME=/home/zhg/Mine/Android/AndroidSdk
export PATH=$PATH:$ANDROID_HOME/tools
export PATH=$PATH:$ANDROID_HOME/platform-tools

# nkd环境变量
export ANDROID_NDK_HOME=/home/zhg/Mine/Android/AndroidSdk/ndk/26.1.10909125
export PATH=$PATH:$ANDROID_NDK_HOME
1
2
3
# 使配置立即生效
source ~/.bashrc

2.6 c++环境

1
2
3
4
5
6
7
8
9
# 安装gcc(C编译器)
sudo apt-get install gcc

# 安装g++(C++编译器)
sudo apt-get install g++

# 安装make
sudo apt-get install make

2.7 Python

检查是否安装Python,Ubuntu 16.04以上默认预装 Python 3

1
2
3
4
python --version

# 或者
python3 --version

3 开始构建

3.1 拉取源码

拉取envoy-mobile项目源码,注意也拉取子模块

1
2
3
4
git clone --recurse-submodules https://github.com/envoyproxy/envoy.git

特定版本
git clone -b v1.28.0 --recurse-submodules https://github.com/envoyproxy/envoy.git

3.2 配置bazel

添加Android构建命令,具体步骤,在项目目录envoy/mobile/.bazelr文件,添加以下命令

1
2
build:release-android --android_cpu=x86,armeabi-v7a,arm64-v8a

3.3 执行构建

在录envoy/mobile/目录打开终端,输入以下命令,执行构建

1
2
./bazelw build android_dist --config=release-android --fat_apk_cpu=x86,armeabi-v7a,arm64-v8a

如果一切顺利,编译一两小时(视cpu性能)就能看到结果,但是基本没有这么顺利的,修复编译报错才是重头戏,下面是一些常见编译错误。

4 构建过程常见错误

4.1 构建命令未定义

错误日志

1
ERROR: Config value 'release-android' is not defined in any .rc file

解决方法

1
2
# 在 .bazelrc 文件中添加以下行来定义 'release-android' 配置:
build:release-android --android_cpu=x86,armeabi-v7a,arm64-v8a

4.2 网络超时(Read timed out)

错误日志

1
2
3
4
5
6
7
ERROR:An error occurred during the fetch of repository 'Maven':
Traceback(most recent call last):
File "/home/zhg/.cache/bazel/bazel_zhg/fdb94f3cc526bbd2b2e68780cd60f6b4/external/rules_jvm_ external/coursier.bzl", line 894, column 17, in _coursier_fetch_impl
_download_jq(repository_ctx)
File "/home/zhg/.cache/bazel/_bazel_zhg/fdb94f3cc526bbd2b2e68780cd60f6b4/external/rules_jvm_external/coursier.bzl",line 876, column 32,in _download_jqrepository_ctx.download(value.url,"jq-%s" % os, sha256 = value.
sha256,executable = True)
Error in download: java.io.IOException: Error downloading [https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64]to /home/zhg/.cache/bazel/_bazelzhg/fdb94f3cc526bbd2b2e68780cd60f6b4/external/maven/jq-linux: Read timed out

原因

网络问题,给终端配置vpn或者代理环境,或者重试

4.3 网络问题(Error fetching)

错误信息

1
2
3
ERROR: /home/zhg/Mine/Workplace/envoy/mobile/library/kotlin/io/envoyproxy/envoymobile/BUILD:9:18: //library/kotlin/io/envoyproxy/envoymobile:envoy_aar_android_javadocs depends on @maven//:org_jetbrains_dokka_dokka_cli in repository @maven which failed to fetch. no such package '@maven//': Error while fetching artifact with coursier: Error fetching artifacts:
https://maven.google.com/androidx/core/core/1.3.2/core-1.3.2.jar: download error: Caught java.net.SocketException (Unexpected end of file from server) while downloading https://maven.google.com/androidx/core/core/1.3.2/core-1.3.2.jar

解决方法

重试或检查网络环境

4.4 Android sdk 版本不匹配

错误日志

1
2
3
4
ERROR: Analysis of target '//:android_dist' failed; build aborted: Android SDK api level 30 was requested but it is not installed in the Android SDK at /home/zhg/Mine/Android/AndroidSdk. The api levels found were [34]. Please choose an available api level or install api level 30 from the Android SDK Manager.
INFO: Elapsed time: 30.879s
INFO: 0 processes.

解决方法

不支持sdk 30以上的版本:打开envoy/mobile/WORKPLACE文件,找到sdk_api_level字段,修改成与所配置的sdk版本一致的版本号

1
2
3
4
5
6
android_configure(
name = "local_config_android",
build_tools_version = "30.0.2",
ndk_api_level = 21,
sdk_api_level = 30,
)

4.5 配置的Android sdk无效

错误信息

1
2
3
Use --sandbox_debug to see verbose messages from the sandbox and retain the sandbox build root for debugging
Error parsing command line: While parsing option --androidJar external/androidsdk/platforms/android-34/android.jar: external/androidsdk/platforms/android-34/android.jar is not a valid path: it does not exist.
Try --help.

解决

检查配置的Android sdk路径或者环境变量

4.6 c++环境报错

错误日志

1
2
Error in fail:
Auto-Configuration Error: Cannot find gcc or CC; either correct your path or set the CC environment variable

解决方法

配置C++环境,安装C/C++编译器和make

1
2
3
4
5
6
7
8
9
// 安装gcc(C编译器)
sudo apt-get install gcc

// 安装g++(C++编译器)
sudo apt-get install g++

// 安装make
sudo apt-get install make

4.7 内存不足(command: Killed)

错误信息

1
2
3
4
5
6
7
8
9

Use --sandbox_debug to see verbose messages from the sandbox and retain the sandbox build root for debugging
clang: error: unable to execute command: Killed
clang: error: linker command failed due to signal (use -v to see invocation)
Target //library/kotlin/io/envoyproxy/envoymobile:envoy_aar_with_artifacts failed to build
INFO: Elapsed time: 5243.412s, Critical Path: 196.75s
INFO: 12923 processes: 801 internal, 12090 linux-sandbox, 32 worker.
FAILED: Build did NOT complete successfully

4.8 内存不足(Not enough space)

错误信息

1
2
OpenJDK 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000600000000, 8589934592, 0) failed; error='Not enough space' (errno=12)

解决方法

envoy mobile构建需要8G或更高的内存大小,检查物理内存或者虚拟机分配的内存大小

5 构建完成

当终端输出Build completed successfully字样时,说明编译成功,congratulations ~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
INFO: From Executing genrule //library/kotlin/io/envoyproxy/envoymobile:envoy_aar:
Constructing aar...
INFO: From Executing genrule //library/kotlin/io/envoyproxy/envoymobile:envoy_aar_with_artifacts:
Outputting pom.xml,sources.jar, and javadocs.jar...
Finished!
Target //library/kotlin/io/envoyproxy/envoymobile:envoy_aar_with_artifacts up-todate:
bazel-bin/library/kotlin/io/envoyproxy/envoymobile/envoy.aar
bazel-bin/library/kotlin/io/envoyproxy/envoymobile/envoy-pom.xml
bazel-bin/library/kotlin/io/envoyproxy/envoymobile/envoy-sources.jar
bazel-bin/library/kotlin/io/envoyproxy/envoymobile/envoy-javadoc.jar
INFO:Elapsed time: 5862.743s, Critical Path: 546.47s
INFO: 13541 processes: 794 internal, 12715 linux-sandbox, 32 worker.
INFO: Build completed successfully, 13541 total actions

构建完成的aar文件在bazel-bin/library/kotlin/io/envoyproxy/envoymobile/envoy.aar目录下,,如果因为文件权限问题无法复制,可以使用以下命令:

1
chmod -R 777 envoy.aar

最后将其复制到Android 项目libs文件夹中使用即可。

总结

成功编译出aar之后,可以把envoy mobile当做普通网络库使用,也可以对envoy mobile的jni部分或者envoy的c端源码进行修改,在移动端实现更多的原来只能运行在Linux或者Windows平台的envoy功能,下篇将展开如何修改源码以实现Android上使用envoy mobile作为前端代理。

参考链接

[1] Envoy Mobile Documentation