派生的 Tomcat Native
netty-tcnative 是 Tomcat Native 的一个派生版本。它包含 Twitter, Inc 贡献的一系列更改,例如
- 简化了本机库的分配和链接
- 项目的完全 Maven 化
- 改进了 OpenSSL 支持
为了最大程度地减轻维护负担,我们为每个稳定的上游版本创建了一个专用分支,并在其基础上应用我们自己的更改,同时将维护的分支数量保持在最少。
netty-tcnative
是一个多模块项目,并构建了一些制品,使其可以在各种环境中使用。
制品 ID | 说明 | 在 Maven Central 上 |
---|---|---|
netty-tcnative-{os_arch} | 这是“默认”制品,动态链接到 libapr-1 和 OpenSSL。要使用此制品,您的系统必须安装并配置 libapr-1 和 OpenSSL。此制品适用于站点管理员可以自由升级 OpenSSL 而无需重建应用程序的生产环境。除非您制作并安装了自己的 APR 和 OpenSSL 构建,否则此版本不支持 Windows。 | 是 |
netty-tcnative-boringssl-static-{os_arch} | 此工件静态链接到 Google 的 boringssl,它是 OpenSSL 的一个分支,具有较小的代码占用空间和附加功能(例如 ALPN),在撰写本文时,这些功能尚未出现在 linux 的稳定版本中。静态链接使得在系统上使用 tcnative 变得更加容易,而无需担心额外的安装步骤。此库不需要 APR。 | 是 |
netty-tcnative-boringssl-static | 这是一个 uber jar,其中包含所有受支持的 netty-tcnative-boringssl-static-{os_arch} 的静态链接库。虽然这往往是一个相当大的 jar,但它极大地简化了入门体验,因为应用程序不必担心为该平台获取正确的 jar。 |
是 |
netty-tcnative-openssl-static-{os_arch} | 此工件静态链接到 libapr-1 和 OpenSSL,使得在系统上使用 tcnative 变得更加容易,而无需担心额外的安装步骤。 | 否 |
netty-tcnative-libressl-static-{os_arch} | 即将推出。 | 否 |
maven 打包在版本 2.0.49.Final
中发生了一些变化。这些变化对 Maven 用户来说很好,但给 Gradle 和 Bazel 用户带来了一些麻烦。
- 对于 Gradle,解决方案是明确声明
tcnative
依赖项和分类器。 - 对于 Bazel,解决方案是使用包含此修复程序的 Bazel 版本:https://github.com/bazelbuild/rules_jvm_external/pull/687
这是最简单的依赖项,因为它不需要特定于平台的分类器
<project>
...
<dependencies>
...
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-tcnative-boringssl-static</artifactId>
<version>2.0.0.Final</version>
</dependency>
...
</dependencies>
...
</project>
在应用程序的 pom.xml
中,添加 os-maven-plugin
扩展和适用于您平台的 netty-tcnative-boringssl-static
依赖项
<project>
...
<dependencies>
...
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-tcnative-boringssl-static</artifactId>
<version>2.0.0.Final</version>
<classifier>${os.detected.classifier}</classifier>
</dependency>
...
</dependencies>
...
<build>
...
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.4.0.Final</version>
</extension>
</extensions>
...
</build>
...
</project>
Netty-tcnative 在部署到 Maven Central 时使用分类器,并为以下平台提供发行版
分类器 | 说明 |
---|---|
windows-x86_64 | Windows 发行版 |
osx-x86_64 | Mac 发行版 |
linux-x86_64 | Linux 发行版 |
在应用程序的 pom.xml
中,添加 os-maven-plugin
扩展和 netty-tcnative
依赖项
<project>
<properties>
<!-- Configure the os-maven-plugin extension to expand the classifier on -->
<!-- Fedora-"like" systems. -->
<os.detection.classifierWithLikes>fedora</os.detection.classifierWithLikes>
</properties>
...
<dependencies>
...
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-tcnative</artifactId>
<version>2.0.0.Final</version>
<classifier>${os.detected.classifier}</classifier>
</dependency>
...
</dependencies>
...
<build>
...
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.4.0.Final</version>
</extension>
</extensions>
...
</build>
...
</project>
在部署到 Maven Central 时,Netty-tcnative 使用分类器为各种平台提供发行版。在 Linux 上需要注意的是,OpenSSL 对 Fedora 衍生版使用与其他 Linux 发行版不同的 soname。从 1.1.33.Fork7
版本开始,我们通过为 Linux 部署两个独立版本(见下表)来解决此限制。
分类器 | 说明 |
---|---|
windows-x86_64 | Windows 发行版(我们建议改用 boringssl;有关复杂情况,请见下文) |
osx-x86_64 | Mac 发行版 |
linux-x86_64 | 用于 Linux 的非 Fedora 衍生版 |
linux-x86_64-fedora | 用于 Fedora 衍生版 |
使用 classifierWithLikes
将配置 os-maven-plugin
以更改生成的 os.detected.classifier
属性。如果您的构建包含依赖于 os.detected.classifier
的其他依赖项,您可以使用 antrun
插件手动创建 netty-tcnative 分类器
<project>
<dependencies>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-tcnative</artifactId>
<version>2.0.0.Final</version>
<classifier>${tcnative.classifier}</classifier>
</dependency>
</dependencies>
<build>
<extensions>
<!-- Use os-maven-plugin to initialize the "os.detected" properties -->
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.4.0.Final</version>
</extension>
</extensions>
<plugins>
<!-- Use Ant to configure the appropriate "tcnative.classifier" property -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>initialize</phase>
<configuration>
<exportAntProperties>true</exportAntProperties>
<target>
<condition property="tcnative.classifier"
value="${os.detected.classifier}-fedora"
else="${os.detected.classifier}">
<isset property="os.detected.release.fedora"/>
</condition>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
要使用基于 OpenSSL 的 SSLEngine
实现,请使用 io.netty.handler.ssl.SslContext
类
public static void main(String[] args) throws Exception {
File certificate = new File("certificate");
File privateKey = new File("privateKey");
SslContext sslContext =
SslContextBuilder.forServer(certificate, privateKey)
.sslProvider(SslProvider.OPENSSL)
.build();
...
}
public class MyChannelInitializer extends ChannelInitializer<SocketChannel> {
private final SslContext sslCtx;
public MyChannelInitializer(SslContext sslCtx) {
this.sslCtx = sslCtx;
}
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
if (sslCtx != null) {
p.addLast(sslCtx.newHandler(ch.alloc()));
}
...
}
}
Netty 将解压缩 netty-tcnative-XXX 工件提供的共享库到一个临时目录中,并使用 java.lang.System.load(String)
加载它。
请注意,netty-tcnative
工件中的共享库是针对 Apache Portable Runtime (APR) 和 OpenSSL 动态链接的。它们必须位于库加载路径中,例如系统库目录、$LD_LIBRARY_PATH
和 %PATH%
。
- 如果您使用的是 Linux,则可能不需要执行任何操作,因为您可以使用系统包管理器安装它们。
- 如果您使用的是 Mac,则必须使用 Homebrew 安装
openssl
包。 - 如果您使用的是 Windows,则必须
- 自行构建 APR,
- 安装 适用于 Windows 的 OpenSSL,以及
- 将包含 .DLL 文件的目录添加到
%PATH%
。
重要提示:如果您使用 Linux 并希望使用 ALPN(您将需要此功能来使用 http2),则需要确保已安装 openssl >= 1.0.2。如果您的发行版的包系统未提供此功能,则需要自行编译并设置 LD_LIBRARY_PATH,如 如何构建 中所述。
如果在 Fedora 30 或更高版本上运行 dnf -y install libxcrypt-compat
以安装必要的依赖项。
如果您错过了此操作,您很可能会看到类似“libcrypt.so.1: 无法打开共享对象文件:没有这样的文件或目录”的错误。
通常不需要自行构建 netty-tcnative
,因为我们正式发布了包含 Linux x86_64
、Mac OS X x86_64
和 Windows x86_64
的本机库的 JAR。如果您正在寻找 SNAPSHOT 构建,请浏览 Sonatype Snapshots。
如果您在平台上,我们不会使用本机库(例如 Windows x86_32)提供 JAR,请按照本部分中的说明进行操作。
在您自己构建时,验证第三方依赖项的完整性非常重要。此外,构建中的依赖项更新将触发校验和失败,并且在更新校验和以匹配之前,软件包维护者应遵循此流程以确保软件包的完整性。
- 从 http://ftp.gnu.org/gnu/autoconf/autoconf-X.Y.Z.tar.gz 下载 tgz 和 tgz.sig
gpg --keyserver keys.gnupg.net --recv-keys 2527436A
gpg --verify autoconf-X.Y.Z.tar.gz.sig
- 从 https://apr.apache.org/download.cgi 下载
- 安全地获取 apr 的 MD5 和:apache 网站链接到 http,但将其修改为 https
- 将和粘贴到文件中
- 验证和
md5 -r apr-X.Y.Z.tar.gz | cut -d " " -f 1 | diff -u apr-X.Y.Z.tar.gz.md5 -
- 签名公钥:RWQg/nutTVqCUVUw8OhyHt9n51IC8mdQRd1b93dOyVrwtIXmMI+dtGFe
- (您可以在 https://www.openbsd.org/libressl/signing.html 下载公钥)
- 从 http://ftp.openbsd.org/pub/OpenBSD/LibreSSL/ 下载 tarball、签名和 SHA256.sig
- 使用 https://www.openbsd.org/libressl/signing.html 中的 libressl.pub 验证:
signify -C -x SHA256.sig -p /path/to/libressl.pub libressl-X.Y.Z.tar.gz
- 从 https://www.openssl.org/source/ 下载 tarball 和 SHA256 签名
- 验证和
sha1sum openssl-X.Y.Z.tar.gz | cut -d " " -f 1 | diff -u openssl-X.Y.Z.tar.gz.sha256 -
boringssl 目前未针对 tcnative 构建进行密封版本控制:相反,它只是在构建时从 上游 Google git 仓库 中的 chromium-stable
分支中提取
先决条件 | 说明 |
---|---|
基本工具 | autoconf、automake、libtool、glibc-devel、make、tar、[xutils-dev 或 imake] |
APR | apr-devel 或 libapr1-dev |
OpenSSL | openssl-devel 或 libssl-dev |
GCC | 需要版本 >= 4.8 |
CMake | 需要版本 >= 2.8.8 |
Perl | 需要版本 >= 5.6.1 |
Ninja | 需要版本 >= 1.3.4 |
Go | 需要版本 >= 1.5.1 |
构建包并将其安装到本地 Maven 存储库
git clone https://github.com/netty/netty-tcnative.git
cd netty-tcnative
# To build a specific version: (e.g. netty-tcnative-2.0.0.Final)
git checkout netty-tcnative-[version]
# To build a snapshot: (e.g. 2.0.0.Final)
git checkout [branch]
./mvnw clean install
要在 IBM Z(s390x)上的 Linux 上构建 `netty-tcnative` 库,请按照此处提供的说明进行操作,并将其安装到本地 Maven 存储库。
首先,您需要安装Xcode。之后,请确保也安装命令行工具
xcode-select --install
克隆 `netty-tcnative` 存储库,并使用Homebrew安装所需的包
git clone https://github.com/netty/netty-tcnative.git
cd netty-tcnative
brew bundle
构建包并将其安装到本地 Maven 存储库
# To build a specific version: (e.g. netty-tcnative-2.0.0.Final)
git checkout netty-tcnative-[version]
# To build a snapshot: (e.g. 2.0.0.Final)
git checkout [branch]
./mvnw clean install
本部分介绍如何在 64 位 Windows 上构建。在 32 位系统上构建时,可能需要调整其中一些步骤。
安装以下包
- Visual C++ 2013 Express
- Windows 10 SDK
-
CMake
- 在安装期间,选择“将 CMake 添加到当前用户的系统 PATH”
- Perl
-
Ninja
- 将可执行文件解压到 `C:\Workspaces\`,并将 `C:\Workspaces` 添加到 `PATH`
- Go
-
Yasm
- 下载到 `C:\Workspaces`
- 设置环境变量 `ASM_NASM=C:\Workspaces\yasm-1.3.0-win64.exe`。
-
OpenSSL.
- 在安装期间,选择“将 OpenSSL DLL 复制到:OpenSSL 二进制文件 (/bin) 目录”
- 设置以下环境变量
OPENSSL_INCLUDE_DIR=C:\OpenSSL-Win64\include
OPENSSL_LIB_DIR=C:\OpenSSL-Win64\lib
-
Apache Portable Runtime (APR) 1.5.2
- 解压到:`C:\Workspaces\apr-1.5.2`
- 在 `C:\Workspaces\apr-1.5.2` 中的命令提示符 (cmd.exe) 中运行以下命令
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86_amd64
nmake /f Makefile.win ARCH="x64 Release" PREFIX=..\apr-1.5.2-dist buildall install
xcopy include\arch\win32\*.h ..\apr-1.5.2-dist\include /d
xcopy include\arch\*.h ..\apr-1.5.2-dist /d
- 设置以下环境变量
APR_INCLUDE_DIR=C:\Workspaces\apr-1.5.2-dist\include
APR_LIB_DIR=C:\Workspaces\apr-1.5.2-dist\lib
现在,启动命令提示符 (cmd.exe) 并加载 Visual C++ 所需的环境变量
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86_amd64
克隆 `netty-tcnative` 并构建它
git clone https://github.com/netty/netty-tcnative.git
cd netty-tcnative
REM To build a specific version: (e.g. netty-tcnative-2.0.0.Final)
git checkout netty-tcnative-[version]
REM To build a snapshot: (e.g. 2.0.0.Final)
git checkout [branch]
mvnw clean install
签出分支 `bootstrap` 并使用上游 tcnative 版本运行 `new-fork` 脚本,将带您进入一个新的完全 maven 化的分支,其名称与上游 tcnative 版本相同。例如
$ git checkout bootstrap
$ ./new-fork 1.1.29 1
将创建一个名为 1.1.29
的新分支,其中包含 tcnative-1.1.29
的 maven 化分支。请注意,该分支不包含任何将更改 tcnative
的主源代码的补丁。您可能需要从已打过补丁的其他分支中挑选一些提交。