Compare commits

...
8 Commits
Author SHA1 Message Date
Zhao Jianing d3dad6c1cf Merge 8630cc0993 into fa0a952f1e 2026-09-15 14:36:17 +08:00
Duansg fa0a952f1e [doc] fix the release and verification guides, document native collector requirements (#4381) 2026-09-14 14:05:29 +08:00
Duansg 3a33d8e96c [doc] cover the native collector packages in the release guide (#4380) 2026-09-14 10:15:14 +08:00
Duansg a85bd46c18 [fix] make the Windows native collector start, and smoke test the packages in CI (#4379) 2026-09-13 19:18:08 +08:00
Duansg ec061f87db [doc] update the architecture diagram in READMEs and CONTRIBUTING (#4378) 2026-09-13 00:15:09 +08:00
Duansg 79d15ed5de [fix] register JMX value types via metadata instead of enable-monitoring (#4377) 2026-09-12 21:36:43 +08:00
Duansg 3089f72580 [fix] make the native collector start: wire up native hints and fix MXBean introspection (#4375) 2026-09-10 08:20:53 +08:00
zjncs 8630cc0993 fix(common): parse +Inf/-Inf as real infinity in StrBuffer.parseDouble
StrBuffer.parseDouble returned the raw IEEE-754 bit-pattern constants
0x7FF0000000000000L / 0xFFF0000000000000L widened to double
(9.2e18 / -4.5e15) instead of real infinities for the Prometheus
text format special values +inf/-inf. OnlineParser.toDouble already
maps them to Double.POSITIVE_INFINITY/NEGATIVE_INFINITY; align
StrBuffer (used by TextParser) with that behavior and drop the
+/-Inf exclusion from the cross-parser test that papered over the
divergence.

Signed-off-by: zjncs <18910855655@163.com>
2026-09-04 12:36:41 +08:00
21 changed files with 696 additions and 311 deletions
@@ -75,6 +75,63 @@ jobs:
}
"archive=$($package.FullName)" >> $env:GITHUB_OUTPUT
- name: Smoke test native collector package
shell: pwsh
run: |
$ErrorActionPreference = "Stop"
$archive = "${{ steps.package.outputs.archive }}"
$work = Join-Path ([System.IO.Path]::GetTempPath()) "hzb-smoke"
Remove-Item -Recurse -Force $work -ErrorAction SilentlyContinue
New-Item -ItemType Directory -Path $work | Out-Null
if ($archive.EndsWith(".zip")) {
Expand-Archive -Path $archive -DestinationPath $work -Force
} else {
tar -xzf $archive -C $work
}
$binary = Get-ChildItem -Path $work -Recurse -File |
Where-Object { $_.Name -like "apache-hertzbeat-collector-native-*" -and $_.Name -notlike "*.txt" } |
Where-Object { $_.Length -gt 10MB } | Select-Object -First 1
if (-not $binary) { throw "native executable not found in $archive" }
$conf = Join-Path $binary.DirectoryName "config"
Write-Host "executable: $($binary.FullName)"
$out = Join-Path $work "stdout.log"
$err = Join-Path $work "stderr.log"
$env:MANAGER_HOST = "127.0.0.1"
$env:IDENTITY = "ci-smoke-${{ matrix.platform }}"
$proc = Start-Process -FilePath $binary.FullName `
-ArgumentList "--spring.config.location=$conf$([IO.Path]::DirectorySeparatorChar)" `
-RedirectStandardOutput $out -RedirectStandardError $err -PassThru
# The collector prints "Started Collector" before the runners execute, and past
# failures crashed after that line, so wait for the ServiceLoader registration too
# and then confirm the process is still alive.
$deadline = (Get-Date).AddSeconds(90)
$registered = $false
while ((Get-Date) -lt $deadline) {
Start-Sleep -Seconds 2
$log = (Get-Content $out, $err -ErrorAction SilentlyContinue) -join "`n"
if ($log -match "collect strategies") { $registered = $true; break }
if ($proc.HasExited) { break }
}
Start-Sleep -Seconds 10
$proc.Refresh()
$alive = -not $proc.HasExited
$exitCode = if ($alive) { $null } else { $proc.ExitCode }
if ($alive) { Stop-Process -Id $proc.Id -Force -ErrorAction SilentlyContinue }
$log = (Get-Content $out, $err -ErrorAction SilentlyContinue) -join "`n"
Write-Host "----- collector output (tail) -----"
Write-Host (($log -split "`n") | Select-Object -Last 40 | Out-String)
Write-Host "-----------------------------------"
if (-not $alive) { throw "collector process exited (exit code $exitCode)" }
if (-not $registered) { throw "collector stayed up but never registered its collect strategies" }
Write-Host "smoke test passed for ${{ matrix.platform }}"
- name: Upload native collector package
uses: actions/upload-artifact@v4
with:
+2 -2
View File
@@ -131,7 +131,7 @@ Add WeChat account `ahertzbeat` to pull you into the WeChat group.
## 🥐 Architecture
![hertzBeat](home/static/img/docs/hertzbeat-arch.png)
![hertzBeat](home/static/img/docs/hertzbeat-architecture.png)
<br>
@@ -271,4 +271,4 @@ Add WeChat account `ahertzbeat` to pull you into the WeChat group.
### 模块
![hertzBeat](home/static/img/docs/hertzbeat-arch.png)
![hertzBeat](home/static/img/docs/hertzbeat-architecture.png)
+1 -1
View File
@@ -47,7 +47,7 @@
## 🥐 Architecture
![HertzBeat](home/static/img/docs/hertzbeat-arch.png)
![HertzBeat](home/static/img/docs/hertzbeat-architecture.png)
## 🐕 Quick Start
+1 -1
View File
@@ -47,7 +47,7 @@
## 🥐 模块
![hertzBeat](home/static/img/docs/hertzbeat-arch.png)
![hertzBeat](home/static/img/docs/hertzbeat-architecture.png)
## 🐕 快速开始
+1 -1
View File
@@ -46,7 +46,7 @@
## 🥐 モジュール
![hertzBeat](home/static/img/docs/hertzbeat-arch.png)
![hertzBeat](home/static/img/docs/hertzbeat-architecture.png)
## 🐕 クイックスタート
@@ -73,11 +73,26 @@ public class RedisCommonCollectImpl extends AbstractCollect {
private static final String UNIQUE_IDENTITY = "identity";
private final ClientResources defaultClientResources;
private final GlobalConnectionCache connectionCache = GlobalConnectionCache.getInstance();
public RedisCommonCollectImpl() {
defaultClientResources = DefaultClientResources.create();
/**
* Holds the lettuce client resources, created on first use.
* <p>
* Loading {@link DefaultClientResources} runs a static initializer that resolves netty's DNS
* address resolver group. That resolver is unavailable in a native image on Windows, where it
* fails with a NullPointerException from sun.net.dns.ResolverConfigurationImpl
* (see oracle/graal#11280 and oracle/graal#4304). Because every collector is instantiated
* eagerly through the ServiceLoader at startup, doing this in the constructor took the whole
* collector process down before it could serve anything. Deferring it keeps startup working;
* on the platforms where the resolver is broken only Redis collection fails, and it fails with
* a clear error at collect time.
*/
private static final class ClientResourcesHolder {
private static final ClientResources INSTANCE = DefaultClientResources.create();
}
private static ClientResources clientResources() {
return ClientResourcesHolder.INSTANCE;
}
@Override
@@ -292,7 +307,7 @@ public class RedisCommonCollectImpl extends AbstractCollect {
* @return redis cluster client
*/
private RedisClusterClient buildClusterClient(RedisProtocol redisProtocol, String host, String port) {
return RedisClusterClient.create(defaultClientResources, redisUri(redisProtocol, host, port));
return RedisClusterClient.create(clientResources(), redisUri(redisProtocol, host, port));
}
/**
@@ -302,7 +317,7 @@ public class RedisCommonCollectImpl extends AbstractCollect {
* @return redis single client
*/
private RedisClient buildSingleClient(RedisProtocol redisProtocol, String host, String port) {
return RedisClient.create(defaultClientResources, redisUri(redisProtocol, host, port));
return RedisClient.create(clientResources(), redisUri(redisProtocol, host, port));
}
private RedisURI redisUri(RedisProtocol redisProtocol, String host, String port) {
@@ -108,11 +108,8 @@ class OnlineParserTest {
MetricFamily metricFamily1 = metricFamilyMap1.get(metricFamilyName);
Set<Double> metricValueSet = metricFamily2.getMetricList().stream().map(MetricFamily.Metric::getValue).collect(Collectors.toSet());
metricFamily1.getMetricList().forEach(metric -> {
// this is for something different between two algorithms above, and both of them is current on this parsing behavior.
if (!(metric.getValue() == Double.POSITIVE_INFINITY || metric.getValue() == Double.NEGATIVE_INFINITY)) {
if (!metricValueSet.contains(metric.getValue())) {
fail();
}
if (!metricValueSet.contains(metric.getValue())) {
fail();
}
});
});
@@ -0,0 +1,25 @@
{
"comment": "Hand-written native hints for the native collector. NOTE: must NOT live under org.apache.hertzbeat/hertzbeat-collector-collector/ - Spring AOT generates reachability-metadata.json at that exact path and silently overwrites it.",
"reflection": [
{"type": "org.apache.coyote.AbstractProtocol", "allPublicMethods": true},
{"type": "org.apache.coyote.http11.AbstractHttp11Protocol", "allPublicMethods": true},
{"type": "org.apache.coyote.http11.Http11NioProtocol", "allPublicMethods": true},
{"type": "io.netty.channel.kqueue.KQueueDatagramChannel", "allPublicConstructors": true},
{"type": "io.netty.channel.kqueue.KQueueSocketChannel", "allPublicConstructors": true},
{"type": "io.netty.channel.kqueue.KQueueEventLoopGroup", "allPublicConstructors": true},
{"type": "io.netty.channel.epoll.EpollDatagramChannel", "allPublicConstructors": true},
{"type": "io.netty.channel.epoll.EpollSocketChannel", "allPublicConstructors": true},
{"type": "io.netty.channel.epoll.EpollEventLoopGroup", "allPublicConstructors": true},
{"type": "io.netty.channel.socket.nio.NioDatagramChannel", "allPublicConstructors": true},
{"type": "io.netty.channel.socket.nio.NioSocketChannel", "allPublicConstructors": true},
{"type": "io.netty.channel.nio.NioEventLoopGroup", "allPublicConstructors": true},
{"type": "java.lang.management.ThreadInfo", "allPublicMethods": true},
{"type": "java.lang.management.LockInfo", "allPublicMethods": true},
{"type": "java.lang.management.MonitorInfo", "allPublicMethods": true},
{"type": "java.lang.StackTraceElement", "allPublicMethods": true},
{"type": "java.lang.management.MemoryUsage", "allPublicMethods": true},
{"type": "com.sun.management.GcInfo", "allPublicMethods": true}
]
}
@@ -1,54 +0,0 @@
[
{
"name": "org.apache.hertzbeat.collector.Collector__ApplicationContextInitializer",
"allDeclaredConstructors": true,
"allDeclaredMethods": true
},
{
"name": "org.apache.hertzbeat.collector.Collector__BeanFactoryRegistrations",
"allDeclaredConstructors": true,
"allDeclaredMethods": true
},
{
"name": "org.apache.hertzbeat.common.entity.dto.ServerInfo",
"allDeclaredConstructors": true,
"allDeclaredFields": true,
"allDeclaredMethods": true
},
{
"name": "io.netty.channel.kqueue.KQueueDatagramChannel",
"allPublicConstructors": true
},
{
"name": "io.netty.channel.kqueue.KQueueSocketChannel",
"allPublicConstructors": true
},
{
"name": "io.netty.channel.kqueue.KQueueEventLoopGroup",
"allPublicConstructors": true
},
{
"name": "io.netty.channel.epoll.EpollDatagramChannel",
"allPublicConstructors": true
},
{
"name": "io.netty.channel.epoll.EpollSocketChannel",
"allPublicConstructors": true
},
{
"name": "io.netty.channel.epoll.EpollEventLoopGroup",
"allPublicConstructors": true
},
{
"name": "io.netty.channel.socket.nio.NioDatagramChannel",
"allPublicConstructors": true
},
{
"name": "io.netty.channel.socket.nio.NioSocketChannel",
"allPublicConstructors": true
},
{
"name": "io.netty.channel.nio.NioEventLoopGroup",
"allPublicConstructors": true
}
]
@@ -1,37 +0,0 @@
org.apache.hertzbeat.collector.collect.http.HttpCollectImpl
org.apache.hertzbeat.collector.collect.http.SslCertificateCollectImpl
org.apache.hertzbeat.collector.collect.database.JdbcCommonCollect
org.apache.hertzbeat.collector.collect.icmp.IcmpCollectImpl
org.apache.hertzbeat.collector.collect.jmx.JmxCollectImpl
org.apache.hertzbeat.collector.collect.redis.RedisCommonCollectImpl
org.apache.hertzbeat.collector.collect.mongodb.MongodbSingleCollectImpl
org.apache.hertzbeat.collector.collect.rocketmq.RocketmqSingleCollectImpl
org.apache.hertzbeat.collector.collect.snmp.SnmpCollectImpl
org.apache.hertzbeat.collector.collect.ssh.SshCollectImpl
org.apache.hertzbeat.collector.collect.telnet.TelnetCollectImpl
org.apache.hertzbeat.collector.collect.smtp.SmtpCollectImpl
org.apache.hertzbeat.collector.collect.ntp.NtpCollectImpl
org.apache.hertzbeat.collector.collect.websocket.WebsocketCollectImpl
org.apache.hertzbeat.collector.collect.ftp.FtpCollectImpl
org.apache.hertzbeat.collector.collect.udp.UdpCollectImpl
org.apache.hertzbeat.collector.collect.dns.DnsCollectImpl
org.apache.hertzbeat.collector.collect.nginx.NginxCollectImpl
org.apache.hertzbeat.collector.collect.memcached.MemcachedCollectImpl
org.apache.hertzbeat.collector.collect.nebulagraph.NebulaGraphCollectImpl
org.apache.hertzbeat.collector.collect.pop3.Pop3CollectImpl
org.apache.hertzbeat.collector.collect.registry.RegistryImpl
org.apache.hertzbeat.collector.collect.redfish.RedfishCollectImpl
org.apache.hertzbeat.collector.collect.nebulagraph.NgqlCollectImpl
org.apache.hertzbeat.collector.collect.imap.ImapCollectImpl
org.apache.hertzbeat.collector.collect.script.ScriptCollectImpl
org.apache.hertzbeat.collector.collect.mqtt.MqttCollectImpl
org.apache.hertzbeat.collector.collect.ipmi2.IpmiCollectImpl
org.apache.hertzbeat.collector.collect.kafka.KafkaCollectImpl
org.apache.hertzbeat.collector.collect.sd.HttpSdCollectImpl
org.apache.hertzbeat.collector.collect.sd.NacosSdCollectImpl
org.apache.hertzbeat.collector.collect.sd.DnsSdCollectImpl
org.apache.hertzbeat.collector.collect.sd.EurekaSdCollectImpl
org.apache.hertzbeat.collector.collect.sd.ConsulSdCollectImpl
org.apache.hertzbeat.collector.collect.modbus.ModbusCollectImpl
org.apache.hertzbeat.collector.collect.s7.S7CollectImpl
org.apache.hertzbeat.collector.collect.sd.ZookeeperSdCollectImpl
@@ -153,9 +153,9 @@ public class StrBuffer {
*/
public static double parseDouble(String s) {
if (POSITIVE_INF.equalsIgnoreCase(s)) {
return POSITIVE_INF_VALUE;
return Double.POSITIVE_INFINITY;
} else if (NEGATIVE_INF.equalsIgnoreCase(s)) {
return NEGATIVE_INF_VALUE;
return Double.NEGATIVE_INFINITY;
}
return Double.parseDouble(s);
}
@@ -91,10 +91,10 @@ class StrBufferTest {
assertEquals(123.45, buffer.toDouble());
buffer = new StrBuffer("+inf");
assertEquals(POSITIVE_INF_VALUE, buffer.toDouble());
assertEquals(Double.POSITIVE_INFINITY, buffer.toDouble());
buffer = new StrBuffer("-inf");
assertEquals(NEGATIVE_INF_VALUE, buffer.toDouble());
assertEquals(Double.NEGATIVE_INFINITY, buffer.toDouble());
}
@Test
@@ -144,8 +144,8 @@ class StrBufferTest {
void testParseDouble() {
assertEquals(123.45, StrBuffer.parseDouble("123.45"));
assertEquals(POSITIVE_INF_VALUE, StrBuffer.parseDouble("+inf"));
assertEquals(NEGATIVE_INF_VALUE, StrBuffer.parseDouble("-inf"));
assertEquals(Double.POSITIVE_INFINITY, StrBuffer.parseDouble("+inf"));
assertEquals(Double.NEGATIVE_INFINITY, StrBuffer.parseDouble("-inf"));
}
}
+81 -32
View File
@@ -4,7 +4,24 @@ title: How to Release
sidebar_position: 4
---
This tutorial describes in detail how to release Apache HertzBeat™, take the release of version 1.7.3 as an example.
This tutorial describes in detail how to release Apache HertzBeat™.
:::caution Before you start: placeholders used in this document
The commands and mail templates below use placeholders. Replace every one of them with your own
values before running anything — **do not copy and paste as is**.
| Placeholder | Meaning | Example |
| --- | --- | --- |
| `{version}` | Release version | `1.9.0` |
| `RC1` | Release candidate number, starts at 1 and goes up on every re-vote | `RC2` |
| `<YOUR_APACHE_ID>` | Your Apache LDAP user name | `duansg` |
| `<YOUR_APACHE_ID>@apache.org` | Your Apache mail address | `duansg@apache.org` |
| `<YOUR_KEY_ID>` | Your short GPG key ID, from `gpg --keyid-format SHORT --list-keys` | `EF04C474` |
| `<YOUR_NAME>` | The name you sign mails with | `Duan SiGuo` |
Command **output** samples in this document keep concrete values so you can compare the shape of
the output; what you see will contain your own key and address.
:::
## 1. Environmental requirements
@@ -23,10 +40,10 @@ This release process is operated in the UbuntuOS(Windows,Mac), and the following
> First summarize the account information to better understand the operation process, will be used many times later.
>
> - apache id: `muchunjin (APACHE LDAP UserName)`
> - apache id: `<YOUR_APACHE_ID>` (APACHE LDAP UserName)
> - apache passphrase: `APACHE LDAP Passphrase`
> - apache email: `muchunjin@apache.org`
> - gpg real name: `muchunjin (Any name can be used, here I set it to the same name as the apache id)`
> - apache email: `<YOUR_APACHE_ID>@apache.org`
> - gpg real name: `<YOUR_APACHE_ID>` (Any name can be used, using the same name as the apache id is recommended)
> - gpg key passphrase: `The password set when creating the gpg key, you need to remember this password`
### 2.1 Key generation
@@ -59,8 +76,8 @@ Is this correct? (y/N) y # Please enter y here
GnuPG needs to construct a user ID to identify your key.
Real name: muchunjin # Please enter 'gpg real name'
Email address: muchunjin@apache.org # Please enter your apache email address here
Real name: <YOUR_APACHE_ID> # Please enter 'gpg real name'
Email address: <YOUR_APACHE_ID>@apache.org # Please enter your apache email address here
Comment: apache key # Please enter some comments here
You selected this USER-ID:
"muchunjin (apache key) [muchunjin@apache.org](mailto:muchunjin@apache.org)"
@@ -114,7 +131,7 @@ uid [ultimate] muchunjin (apache key) [muchunjin@apache.org](mailto:much
sub rsa4096/0C5A4E1C 2023-05-01 [E]
# Send public key to keyserver via key id
$ gpg --keyserver keyserver.ubuntu.com --send-key 05016886
$ gpg --keyserver hkps://keyserver.ubuntu.com:443 --send-key <YOUR_KEY_ID>
# Among them, keyserver.ubuntu.com is the selected keyserver, it is recommended to use this, because the Apache Nexus verification uses this keyserver
```
@@ -123,7 +140,7 @@ $ gpg --keyserver keyserver.ubuntu.com --send-key 05016886
Verify whether it is synchronized to the public network, it will take about a minute to find out the answer, if not successful, you can upload and retry multiple times.
```shell
$ gpg --keyserver keyserver.ubuntu.com --recv-keys 05016886 # If the following content appears, it means success
$ gpg --keyserver hkps://keyserver.ubuntu.com:443 --recv-key <YOUR_KEY_ID> # If the following content appears, it means success
gpg: key ACFB69E705016886: "muchunjin (apache key) [muchunjin@apache.org](mailto:muchunjin@apache.org)" not changed
gpg: Total number processed: 1
gpg: unchanged: 1
@@ -146,9 +163,9 @@ $ svn co https://dist.apache.org/repos/dist/dev/hertzbeat
$ cd svn/dev/hertzbeat
# Append the KEY you generated to the file KEYS, and check if it is added correctly
$ (gpg --list-sigs muchunjin@apache.org && gpg --export --armor muchunjin@apache.org) >> KEYS
$ (gpg --list-sigs <YOUR_APACHE_ID>@apache.org && gpg --export --armor <YOUR_APACHE_ID>@apache.org) >> KEYS
$ svn ci -m "add gpg key for muchunjin"
$ svn ci -m "add gpg key for <YOUR_APACHE_ID>"
```
##### 2.4.2 Add public key to KEYS in release branch
@@ -161,9 +178,9 @@ $ svn co https://dist.apache.org/repos/dist/release/hertzbeat
$ cd svn/release/hertzbeat
# Append the KEY you generated to the file KEYS, and check if it is added correctly
$ (gpg --list-sigs muchunjin@apache.org && gpg --export --armor muchunjin@apache.org) >> KEYS
$ (gpg --list-sigs <YOUR_APACHE_ID>@apache.org && gpg --export --armor <YOUR_APACHE_ID>@apache.org) >> KEYS
$ svn ci -m "add gpg key for muchunjin"
$ svn ci -m "add gpg key for <YOUR_APACHE_ID>"
```
## 3. Prepare material package & release
@@ -205,16 +222,16 @@ then
mvn clean install
```
> Build HertzBeat collector binary, run script in `collector`
> Build HertzBeat collector binary, run script in the project root directory
```shell
mvn clean package -Pcluster
mvn clean package -pl hertzbeat-collector/hertzbeat-collector-collector -am -Pcluster
```
> Build the native collector binary for the current host with GraalVM JDK 25 and `native-image`
```shell
mvn clean package -pl hertzbeat-collector-collector -am -Pnative
mvn clean package -pl hertzbeat-collector/hertzbeat-collector-collector -am -Pnative -DskipTests
```
> The repository workflow `.github/workflows/collector-native-build.yml` is a release helper, not a regular PR or push CI workflow.
@@ -227,11 +244,15 @@ The release package are here:
- `dist/apache-hertzbeat-collector-{version}-bin.tar.gz`
- `dist/apache-hertzbeat-collector-native-{version}-linux-amd64-bin.tar.gz`
- `dist/apache-hertzbeat-collector-native-{version}-linux-arm64-bin.tar.gz`
- `dist/apache-hertzbeat-collector-native-{version}-macos-amd64-bin.tar.gz`
- `dist/apache-hertzbeat-collector-native-{version}-macos-arm64-bin.tar.gz`
- `dist/apache-hertzbeat-collector-native-{version}-windows-amd64-bin.zip`
- `dist/apache-hertzbeat-{version}-docker-compose.tar.gz`
> **Start each native collector package once before signing it.** A native package has shipped
> green from the build while crashing immediately on startup, and neither signing nor uploading
> catches that. Unpack it, run `bin/startup.sh` (`bin\startup.bat` on Windows), and confirm the log
> shows `Started Collector` and `Registered N collect strategies`, and that the process is still
> alive ten seconds later.
#### 3.4 Package the source code
> Package the project source code
@@ -250,18 +271,29 @@ The archive package is here `dist/apache-hertzbeat-1.7.3-src.tar.gz`
#### 3.5 Sign binary and source packages
> The `gpg -u 33545C76` `33545C76` is your gpg secret ID, see from `gpg --keyid-format SHORT --list-keys`
> `<YOUR_KEY_ID>` is your short gpg key ID, see from `gpg --keyid-format SHORT --list-keys`
```shell
cd dist
# sign
for i in *.tar.gz; do echo $i; gpg -u 33545C76 --armor --output $i.asc --detach-sig $i ; done
# sign, skipping artifacts that already have a signature
for i in *.tar.gz *.zip; do
[ -e "$i.asc" ] || { echo "sign: $i"; gpg -u <YOUR_KEY_ID> --armor --output "$i.asc" --detach-sig "$i"; }
done
# SHA512
for i in *.tar.gz; do echo $i; sha512sum $i > $i.sha512 ; done
# SHA512 checksums, skipping artifacts that already have one
for i in *.tar.gz *.zip; do
[ -e "$i.sha512" ] || { echo "sha512: $i"; sha512sum "$i" > "$i.sha512"; }
done
# if macos sha512sum not found, you can install by brew install coreutils
# integrity check: every artifact must have both .asc and .sha512
# this catches artifacts a glob missed, e.g. *.tar.gz alone skips the Windows .zip
for i in *.tar.gz *.zip; do
[ -e "$i.asc" ] || echo "MISSING SIGNATURE: $i"
[ -e "$i.sha512" ] || echo "MISSING CHECKSUM: $i"
done
```
> The final file list is as follows
@@ -279,6 +311,15 @@ apache-hertzbeat-1.7.3-docker-compose.tar.gz.sha512
apache-hertzbeat-collector-1.7.3-bin.tar.gz
apache-hertzbeat-collector-1.7.3-bin.tar.gz.asc
apache-hertzbeat-collector-1.7.3-bin.tar.gz.sha512
apache-hertzbeat-collector-native-1.9.0-linux-amd64-bin.tar.gz
apache-hertzbeat-collector-native-1.9.0-linux-amd64-bin.tar.gz.asc
apache-hertzbeat-collector-native-1.9.0-linux-amd64-bin.tar.gz.sha512
apache-hertzbeat-collector-native-1.9.0-linux-arm64-bin.tar.gz
apache-hertzbeat-collector-native-1.9.0-linux-arm64-bin.tar.gz.asc
apache-hertzbeat-collector-native-1.9.0-linux-arm64-bin.tar.gz.sha512
apache-hertzbeat-collector-native-1.9.0-windows-amd64-bin.zip
apache-hertzbeat-collector-native-1.9.0-windows-amd64-bin.zip.asc
apache-hertzbeat-collector-native-1.9.0-windows-amd64-bin.zip.sha512
```
#### 3.6 Verify signature
@@ -327,14 +368,16 @@ apache-hertzbeat-collector-1.7.3-bin.tar.gz: OK
# Check out the dev directory of the Apache SVN to the svn/dev directory under dist in the root directory of the Apache HertzBeat™ project
svn co https://dist.apache.org/repos/dist/dev/hertzbeat svn/dev
svn co --depth empty https://dist.apache.org/repos/dist/dev/hertzbeat
# alternative: check out an empty working copy when you do not want to download
# every past release candidate
# svn co --depth empty https://dist.apache.org/repos/dist/dev/hertzbeat svn/dev
```
- Copy the material package to the dev directory
Create a version number directory and name it in the form of `release_version`-`RC_version`. RC_version starts from 1, that is, the candidate version starts from RC1. During the release process, there is a problem that causes the vote to fail.
If it needs to be corrected, it needs to iterate the RC version , the RC version number needs to be +1. For example: Vote for version 1.7.3-RC1. If the vote passes without any problems, the RC1 version material will be released as the final version material.
If there is a problem (when the hertzbeat/incubator community votes, the voters will strictly check various release requirements and compliance issues) and need to be corrected, then re-initiate the vote after the correction, and the candidate version for the next vote is 1.7.3- RC2.
If there is a problem (when the HertzBeat community votes, the voters will strictly check various release requirements and compliance issues) and need to be corrected, then re-initiate the vote after the correction, and the candidate version for the next vote is 1.7.3- RC2.
```shell
mkdir -p svn/dev/1.7.3-RC1
@@ -368,6 +411,12 @@ svn commit -m "release for HertzBeat 1.7.3"
Send a voting email in the community requires at least three `+1` and no `-1`.
:::caution Check two things before sending
1. **Your public key is already in the KEYS file.** Open [https://downloads.apache.org/hertzbeat/KEYS](https://downloads.apache.org/hertzbeat/KEYS) and search for your address. If it is not there, voters cannot verify your signatures. See 2.4 for how to add it.
2. **Every version and RC number in the template is replaced.** The template below has **five** places to change: the mail subject, the first line of the body, the release notes link, the release candidates link and the git tag link. When the RC number goes up (RC1 to RC2) all five have to move together; missing one confuses the voters.
:::
> `Send to`: [dev@hertzbeat.apache.org](mailto:dev@hertzbeat.apache.org) <br />
> `Title`: [VOTE] Release Apache HertzBeat™ 1.7.3 rc1 <br />
> `Body`:
@@ -388,7 +437,7 @@ https://dist.apache.org/repos/dist/dev/hertzbeat/1.7.3-RC1/
Git tag for the release:
https://github.com/apache/hertzbeat/releases/tag/v1.7.3-rc1
The artifacts signed with PGP key [33545C76], corresponding to [muchunjin@apache.org], that can be found in keys file:
The artifacts signed with PGP key [<YOUR_KEY_ID>], corresponding to [<YOUR_APACHE_ID>@apache.org], that can be found in keys file:
https://downloads.apache.org/hertzbeat/KEYS
The vote will be open for at least 72 hours or until the necessary number of votes are reached.
@@ -447,20 +496,20 @@ https://lists.apache.org/thread/t01b2lbtqzyt7j4dsbdp5qjc3gngjsdq
Thank you to everyone who helped us to verify and vote for this release. We will move to the ASF Incubator voting shortly.
---
Best,
ChunJin Mu
<YOUR_NAME>
```
One item of the email content is `Vote thread`, and the link is obtained here: [https://lists.apache.org/list.html?dev@hertzbeat.apache.org](https://lists.apache.org/list.html?dev@hertzbeat.apache.org)
## 4. Complete the final publishing steps
## 5. Complete the final publishing steps
### 4.1 Migrating source and binary packages
### 5.1 Migrating source and binary packages
```shell
svn mv https://dist.apache.org/repos/dist/dev/hertzbeat/1.7.3-RC1 https://dist.apache.org/repos/dist/release/hertzbeat/1.7.3 -m "transfer packages for 1.7.3-RC1"
```
#### 4.2 Add the new version download address to the official website
#### 5.2 Add the new version download address to the official website
[https://github.com/apache/hertzbeat/blob/master/home/docs/download.md](https://github.com/apache/hertzbeat/blob/master/home/docs/download.md)
[https://github.com/apache/hertzbeat/blob/master/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/download.md](https://github.com/apache/hertzbeat/blob/master/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/download.md)
@@ -469,7 +518,7 @@ Open the official website address [https://hertzbeat.apache.org/docs/download/](
> It should be noted that the download link may take effect after an hour, so please pay attention to it.
#### 4.3 Generate a release on github
#### 5.3 Generate a release on github
Update pre-release to create a tag named v1.7.3 based on the release-1.7.3-rc1 branch, and set this tag to latest release.
@@ -496,7 +545,7 @@ Then click the `Publish release` button.
The rename the release-1.7.3-rc1 branch to release-1.7.3.
#### 4.5 Send new version announcement email
#### 5.4 Send new version announcement email
> `Send to`: [announce@apache.org](mailto:announce@apache.org) <br />
> `cc`: [dev@hertzbeat.apache.org](mailto:dev@hertzbeat.apache.org) <br />
@@ -527,7 +576,7 @@ HertzBeat Resources:
Apache HertzBeat™ Team
---
Best,
ChunJin Mu
<YOUR_NAME>
```
This version release is over.
+104 -22
View File
@@ -6,7 +6,7 @@ sidebar_position: 4
## Verify the candidate version
For detailed check list, please refer to the official [check list](https://cwiki.apache.org/confluence/display/INCUBATOR/Incubator+Release+Checklist)
For the detailed check list, please refer to the ASF [release policy](https://www.apache.org/legal/release-policy.html) and [release publishing guide](https://infra.apache.org/release-publishing.html)
Version content accessible in browser [https://dist.apache.org/repos/dist/dev/hertzbeat/](https://dist.apache.org/repos/dist/dev/hertzbeat/)
@@ -21,10 +21,13 @@ If the network is poor, downloading may be time-consuming. The download is compl
:::
```shell
#If there is svn locally, you can clone to the local
$ svn co https://dist.apache.org/repos/dist/dev/hertzbeat/`release_version`-`rc_version`/
#or download the material file directly
$ wget https://dist.apache.org/repos/dist/dev/hertzbeat/`release_version`-`rc_version`/xxx.xxx
# Replace {version} and RC1 with the version and candidate under vote, e.g. 1.9.0 and RC2
# if there is svn locally, you can check out the whole directory
$ svn co https://dist.apache.org/repos/dist/dev/hertzbeat/{version}-RC1/
# or download a single artifact directly
$ wget https://dist.apache.org/repos/dist/dev/hertzbeat/{version}-RC1/apache-hertzbeat-{version}-src.tar.gz
```
### 2. Verify that the uploaded version is compliant
@@ -38,7 +41,17 @@ The package uploaded to dist must include the source code package, and the binar
1. Whether to include the source code package
2. Whether to include the signature of the source code package
3. Whether to include the sha512 of the source code package
4. If the binary package is uploaded, also check the contents listed in (2)-(4)
4. If binary packages are uploaded (including the native collector packages), check items 2 and 3 for every one of them
> **Every** artifact must have a matching `.asc` and `.sha512`, with no exception. This loop reports
> anything missing:
>
> ```shell
> for i in *.tar.gz *.zip; do
> [ -e "$i.asc" ] || echo "missing signature: $i"
> [ -e "$i.sha512" ] || echo "missing checksum: $i"
> done
> ```
#### 2.2 Check gpg signature
@@ -47,13 +60,27 @@ First import the publisher's public key. Import KEYS from the svn repository to
##### 2.2.1 Import public key
```shell
-curl https://downloads.apache.org/hertzbeat/KEYS > KEYS # Download KEYS
curl https://downloads.apache.org/hertzbeat/KEYS > KEYS # Download KEYS
gpg --import KEYS # Import KEYS to local
```
##### 2.2.2 Trust the public key
##### 2.2.2 About trusting the public key
Trust the KEY used in this version:
:::tip Verifying a signature does not require trusting the key
`gpg --verify` prints `Good signature` for an untrusted key as well, it only adds a warning:
```text
WARNING: This key is not certified with a trusted signature!
```
**That warning is expected. As long as `Good signature` appears, the check passes.**
If you still want to silence it, you can set a trust level as shown below. Note that
`5 = ultimate` means "this is my own key" in GPG terms, and marking someone else's key ultimate
pollutes your local web of trust, so `4 = fully` is usually the better choice.
:::
Set the trust level of the KEY used in this version (optional):
```shell
$ gpg --edit-key xxxxxxxxxx #KEY user used in this version
@@ -83,7 +110,9 @@ gpg>
##### 2.2.3 Check the gpg signature
```shell
for i in *.tar.gz; do echo $i; gpg --verify $i.asc $i; done
# cover *.zip as well, the Windows native collector package is a zip and a
# *.tar.gz-only loop skips it silently
for i in *.tar.gz *.zip; do echo $i; gpg --verify $i.asc $i; done
```
check result
@@ -100,7 +129,10 @@ gpg: Good signature from "XXX <xxx@apache.org>"
#### 2.3 Check sha512 hash
```shell
for i in *.tar.gz; do echo $i; sha512sum --check $i.sha512; done
for i in *.tar.gz *.zip; do echo $i; sha512sum --check "$i.sha512"; done
# on macOS, if sha512sum is missing, use the bundled shasum instead
# for i in *.tar.gz *.zip; do echo $i; shasum -a 512 -c "$i.sha512"; done
```
#### 2.4 Check the binary package
@@ -121,7 +153,42 @@ check as follows:
- [ ] Able to compile correctly
- [ ] .....
#### 2.5 Check the source package
#### 2.5 Check the native collector packages
The native collector packages (`apache-hertzbeat-collector-native-{version}-*`) are **pre-compiled
native executables**. The source build check below does not apply to them, so check them separately.
```shell
tar -xzf apache-hertzbeat-collector-native-{version}-linux-amd64-bin.tar.gz
cd apache-hertzbeat-collector-native-{version}-linux-amd64-bin
MANAGER_HOST=127.0.0.1 ./bin/startup.sh
tail -f logs/startup.log
```
Check the following:
- [ ] `LICENSE`, `NOTICE` and the `licenses/` directory exist
- [ ] it starts: the log shows `Started Collector` and `Registered N collect strategies`
- [ ] the process is still alive ten seconds later (**a crash can happen after `Started Collector`**,
so that line alone is not enough)
:::caution The native packages have hard runtime requirements
When they are not met the process exits instantly with no log output at all, which is easy to
mistake for a corrupted artifact. Check your environment first:
- **x86 packages need AVX2**: Intel Haswell (2013) and later, AMD Zen (2017) and later. Some
Atom-family low-end chips, Rosetta 2 on Apple Silicon and older Windows on ARM emulation do not
support it
- **Linux packages need glibc 2.34 or newer**: Ubuntu 22.04+, Debian 12+, RHEL/Rocky 9+ work;
Ubuntu 20.04, Debian 11, RHEL 8 and CentOS 7 do not
- **the Windows package needs** Windows 10 / Server 2016 or newer with the Microsoft Visual C++
2015-2022 Redistributable installed
An unmet requirement is a known limitation, not a reason to vote -1. Please state the environment
you verified on in your reply.
:::
#### 2.6 Check the source package
> If the binary/web-binary package is uploaded, check the binary package.
@@ -162,10 +229,11 @@ Non-PMC member:
+1 (non-binding)
I checked:
1. All download links are valid
2. Checksum and signature are OK
3. LICENSE and NOTICE are exist
4. Build successfully on macOS(Big Sur)
5.
2. Checksums and signatures are OK for all artifacts, including the .zip
3. LICENSE and NOTICE exist and are correct
4. Built successfully from source on <your OS and version>
5. Native collector package starts and registers its collect strategies
6.
```
PMC member:
@@ -174,12 +242,26 @@ PMC member:
+1 (binding)
I checked:
1. All download links are valid
2. Checksum and signature are OK
3. LICENSE and NOTICE are exist
4. Build successfully on macOS(Big Sur)
5.
2. Checksums and signatures are OK for all artifacts, including the .zip
3. LICENSE and NOTICE exist and are correct
4. Built successfully from source on <your OS and version>
5. Native collector package starts and registers its collect strategies
6.
```
When you find a problem, give enough detail for the release manager to reproduce it:
```text
-1 (binding)
The <artifact name> is missing its .sha512 checksum.
Checked on: macOS 26 / arm64
Steps:
1. svn co https://dist.apache.org/repos/dist/dev/hertzbeat/1.9.0-RC2/
2. for i in *.tar.gz *.zip; do [ -e "$i.sha512" ] || echo "missing: $i"; done
Output:
missing: apache-hertzbeat-collector-native-1.9.0-windows-amd64-bin.zip
```
---
This doc refer from [Apache StreamPark](https://streampark.apache.org/)
+40 -3
View File
@@ -33,6 +33,43 @@ The native collector package is not a drop-in replacement for every JVM collecto
- The native collector does not support loading external JDBC driver JARs from `ext-lib` at runtime.
- If your deployment depends on JVM-style runtime classpath extension, keep using the JVM collector package.
## Runtime requirements
The native collector is an ahead-of-time compiled executable, so its runtime requirements are
**much stricter** than the JVM collector's. The JVM detects CPU features at startup and adapts;
a native image has its instruction set baked in at build time, with no fallback.
| Platform | Requirement |
| --- | --- |
| Linux / Windows (x86-64) | The CPU must support **AVX2**: Intel Haswell (2013) or newer, AMD Zen (2017) or newer |
| Linux (both architectures) | **glibc 2.34 or newer** |
| Linux (arm64) | ARMv8-A baseline, no extra instruction set required |
| Windows | Windows 10 / Server 2016 or newer, with the **Microsoft Visual C++ 2015-2022 Redistributable** installed |
Common distributions, against the glibc 2.34 line:
| Works | Does not work |
| --- | --- |
| Ubuntu 22.04 / 24.04, Debian 12, RHEL / Rocky / AlmaLinux 9, Amazon Linux 2023 | Ubuntu 20.04, Debian 11, RHEL / Rocky / AlmaLinux 8, CentOS 7, Amazon Linux 2 |
Other environments without AVX2 include some Atom-family low-end chips (J4125, N4020, N5105),
Rosetta 2 on Apple Silicon, and Windows on ARM without the newer Prism emulator.
:::caution The failure modes are misleading
- **No AVX2**: the process exits **instantly, with no output and no log file** (`Illegal instruction`
on Linux, exit code `-1073741795` on Windows)
- **glibc too old**: `version 'GLIBC_2.34' not found`
- **Missing VC++ runtime on Windows**: `VCRUNTIME140_1.dll` not found
The first one is easily mistaken for a corrupted package. If double-clicking does nothing, or the
process starts and prints nothing at all, check for AVX2 support first.
**If any requirement is not met, use the JVM collector package**
`apache-hertzbeat-collector-{version}-bin.tar.gz` instead. It only needs JDK 25 and has none of
these constraints.
:::
## When should I stay on the JVM collector?
Use the JVM collector package if your monitoring depends on external JDBC drivers, especially:
@@ -54,9 +91,9 @@ The native collector package is platform-specific:
Examples:
- `apache-hertzbeat-collector-native-1.8.0-linux-amd64-bin.tar.gz`
- `apache-hertzbeat-collector-native-1.8.0-macos-arm64-bin.tar.gz`
- `apache-hertzbeat-collector-native-1.8.0-windows-amd64-bin.zip`
- `apache-hertzbeat-collector-native-1.9.0-linux-amd64-bin.tar.gz`
- `apache-hertzbeat-collector-native-1.9.0-macos-arm64-bin.tar.gz`
- `apache-hertzbeat-collector-native-1.9.0-windows-amd64-bin.zip`
## Configuration consistency
+14
View File
@@ -14,6 +14,20 @@ Apache HertzBeat's metadata information is stored in H2 or Mysql, PostgreSQL rel
**You need to save and back up the data files of the database and monitoring templates yml files before upgrading**
## New In 1.9.0: Native Collector Packages
Starting with 1.9.0 there are pre-compiled native collector packages
(`apache-hertzbeat-collector-native-*`), which start faster and use less memory.
They are **not a drop-in replacement** for the JVM collector, and they have hard runtime
requirements: AVX2 for the x86 packages, glibc 2.34 or newer for the Linux packages, and the VC++
redistributable for the Windows package. When a requirement is not met the process **exits
instantly with no log output at all**. If you plan to switch, read the runtime requirements in
[Native collector](native-collector) first.
The JVM collector package `apache-hertzbeat-collector-{version}-bin.tar.gz` is still provided and
upgrades the same way as before.
## Breaking Changes In 1.9.0
### SFTP monitors require an explicit host-key policy
@@ -4,7 +4,22 @@ title: 如何进行版本发布
sidebar_position: 4
---
本教程详细描述了如何发布Apache HertzBeat,并以 v1.7.3 版本的发布为例
本教程详细描述了如何发布 Apache HertzBeat。
:::caution 开始之前:本文中需要替换的变量
文中的命令和邮件模板使用了占位符,执行前请全部替换为你自己的值,**不要直接复制粘贴**。
| 占位符 | 含义 | 示例 |
| --- | --- | --- |
| `{version}` | 发布版本号 | `1.9.0` |
| `RC1` | 候选版本号,从 1 开始,每次重新投票 +1 | `RC2` |
| `<YOUR_APACHE_ID>` | 你的 Apache LDAP 用户名 | `duansg` |
| `<YOUR_APACHE_ID>@apache.org` | 你的 Apache 邮箱 | `duansg@apache.org` |
| `<YOUR_KEY_ID>` | 你的 GPG 短密钥 ID`gpg --keyid-format SHORT --list-keys` 可查看 | `EF04C474` |
| `<YOUR_NAME>` | 邮件署名 | `Duan SiGuo` |
文中代码块里的**命令输出示例**(如 `gpg` 的回显、签名校验结果)保留了具体值,仅供对照格式,你实际看到的会是自己的信息。
:::
## 1. 环境要求
@@ -23,10 +38,10 @@ sidebar_position: 4
> 首先整理帐户信息以更好地了解操作过程,稍后会多次使用。
>
> - apache id: `muchunjin (APACHE LDAP 用户名)`
> - apache id: `<YOUR_APACHE_ID>` (APACHE LDAP 用户名)
> - apache passphrase: `APACHE LDAP 密钥`
> - apache email: `muchunjin@apache.org`
> - gpg real name: `muchunjin (任何名称均可用, 在这里我将其设置为与apache id相同的名称)`
> - apache email: `<YOUR_APACHE_ID>@apache.org`
> - gpg real name: `<YOUR_APACHE_ID>` (任何名称均可用, 建议设置为与 apache id 相同的名称)
> - gpg key passphrase: `创建gpg密钥时设置的密码,你需要记住此密码`
### 2.1 生成密钥
@@ -59,11 +74,11 @@ Is this correct? (y/N) y # Please enter y here
GnuPG needs to construct a user ID to identify your key.
Real name: muchunjin # Please enter 'gpg real name'
Email address: muchunjin@apache.org # Please enter your apache email address here
Real name: <YOUR_APACHE_ID> # Please enter 'gpg real name'
Email address: <YOUR_APACHE_ID>@apache.org # Please enter your apache email address here
Comment: apache key # Please enter some comments here
You selected this USER-ID:
"muchunjin (apache key) [muchunjin@apache.org](mailto:muchunjin@apache.org)"
"duansg (apache key) [duansg@apache.org](mailto:duansg@apache.org)"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O # Please enter O here
We need to generate a lot of random bytes. It is a good idea to perform
@@ -90,31 +105,30 @@ generator a better chance to gain enough entropy.
│ │
`<OK>` `<Cancel>`
└─────────────────────────────────────────────────────┘
gpg: key ACFB69E705016886 marked as ultimately trusted
gpg: revocation certificate stored as '/root/.gnupg/openpgp-revocs.d/DC12398CCC33A5349EB9663DF9D970AB18C9EDF6.rev'
gpg: directory '/Users/duansg/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/Users/duansg/.gnupg/openpgp-revocs.d/C787268D3396367EB3C2242402CA7E2CEF04C474.rev'
public and secret key created and signed.
pub rsa4096 2023-05-01 [SC]
85778A4CE4DD04B7E07813ABACFB69E705016886
uid muchunjin (apache key) [muchunjin@apache.org](mailto:muchunjin@apache.org)
sub rsa4096 2023-05-01 [E]
pub rsa4096 2026-07-27 [SC]
C787268D3396367EB3C2242402CA7E2CEF04C474
uid duansg <duansg@apache.org>
sub rsa4096 2026-07-27 [E]
```
密钥可以通过`gpg --list-signatures`命令查看
密钥可以通过`gpg --list-signatures` 或者 `gpg --keyid-format SHORT --list-keys` 命令查看
### 2.2 将生成的密钥上传到公共服务器
```shell
$ gpg --keyid-format SHORT --list-keys
/root/.gnupg/pubring.kbx
------------------------
pub rsa4096/05016886 2023-05-01 [SC]
85778A4CE4DD04B7E07813ABACFB69E705016886
uid [ultimate] muchunjin (apache key) [muchunjin@apache.org](mailto:muchunjin@apache.org)
sub rsa4096/0C5A4E1C 2023-05-01 [E]
pub rsa4096/EF04C474 2026-07-27 [SC]
C787268D3396367EB3C2242402CA7E2CEF04C474
uid [ultimate] duansg <duansg@apache.org>
sub rsa4096/E955F059 2026-07-27 [E]
# Send public key to keyserver via key id
$ gpg --keyserver keyserver.ubuntu.com --send-key 05016886
$ gpg --keyserver hkps://keyserver.ubuntu.com:443 --send-key <YOUR_KEY_ID>
# Among them, keyserver.ubuntu.com is the selected keyserver, it is recommended to use this, because the Apache Nexus verification uses this keyserver
```
@@ -123,8 +137,8 @@ $ gpg --keyserver keyserver.ubuntu.com --send-key 05016886
验证是否已经同步到公共网络,需要一分钟左右才能知道答案,如果不成功,您可以多次上传并重试。
```shell
$ gpg --keyserver keyserver.ubuntu.com --recv-keys 05016886 # If the following content appears, it means success
gpg: key ACFB69E705016886: "muchunjin (apache key) [muchunjin@apache.org](mailto:muchunjin@apache.org)" not changed
gpg --keyserver hkps://keyserver.ubuntu.com:443 --recv-key <YOUR_KEY_ID> # If the following content appears, it means success
gpg: key 02CA7E2CEF04C474: "duansg <duansg@apache.org>" not changed
gpg: Total number processed: 1
gpg: unchanged: 1
```
@@ -138,6 +152,8 @@ gpg: unchanged: 1
##### 2.4.1 将公钥添加到dev分支的KEYS
切换到 HertzBeat 的根目录进行相关操作:
```shell
$ mkdir -p svn/dev
$ cd svn/dev
@@ -146,13 +162,15 @@ $ svn co https://dist.apache.org/repos/dist/dev/hertzbeat
$ cd svn/dev/hertzbeat
# 将生成的KEY追加到KEYS文件中,检查是否添加正确
$ (gpg --list-sigs muchunjin@apache.org && gpg --export --armor muchunjin@apache.org) >> KEYS
$ (gpg --list-sigs <YOUR_APACHE_ID>@apache.org && gpg --export --armor <YOUR_APACHE_ID>@apache.org) >> KEYS
$ svn ci -m "add gpg key for muchunjin"
$ svn ci -m "add gpg key for <YOUR_APACHE_ID>"
```
##### 2.4.2 将公钥添加到release分支的KEYS
切换到 HertzBeat 的根目录进行相关操作:
```shell
$ mkdir -p svn/release
$ cd svn/release
@@ -161,26 +179,26 @@ $ svn co https://dist.apache.org/repos/dist/release/hertzbeat
$ cd svn/release/hertzbeat
# 将生成的KEY追加到KEYS文件中,检查是否添加正确
$ (gpg --list-sigs muchunjin@apache.org && gpg --export --armor muchunjin@apache.org) >> KEYS
$ (gpg --list-sigs <YOUR_APACHE_ID>@apache.org && gpg --export --armor <YOUR_APACHE_ID>@apache.org) >> KEYS
$ svn ci -m "add gpg key for muchunjin"
$ svn ci -m "add gpg key for <YOUR_APACHE_ID>"
```
## 3. 准备物料 & 发布
### 准备发布物料
#### 3.1 基于 master 分支,创建一个名为 release-`release_version`-rcx 的分支,例如 release-1.7.3-rc1。并基于 release-1.7.3-rc1 分支创建一个名为 v1.7.3-rc1 的标签,并将此标签设置为预发布
#### 3.1 基于 master 分支,创建一个名为 release-`release_version`-rcx 的分支,例如 `release-{version}-rc1`。并基于 `release-{version}-rc1` 分支创建一个名为 `v{version}-rc1` 的标签,并将此标签设置为预发布
```shell
git checkout master
git checkout -b release-1.7.3-rc1
git checkout -b release-{version}-rc1
```
#### 3.2 本地切换到待发布分支
```shell
git checkout release-1.7.3-rc1
git checkout release-{version}-rc1
```
#### 3.3 编译二进制包
@@ -205,16 +223,16 @@ mvn clean package -Prelease
mvn clean install
```
> HertzBeat-Collector 编译打包,在项目`collector`目录下执行以下命令
> HertzBeat-Collector 编译打包,在项目目录下执行以下命令
```shell
mvn clean package -Pcluster
mvn clean package -pl hertzbeat-collector/hertzbeat-collector-collector -am -Pcluster
```
> 使用带 `native-image` 的 GraalVM JDK 25,为当前宿主机构建 Native 采集器安装包
```shell
mvn clean package -pl hertzbeat-collector-collector -am -Pnative
mvn clean package -pl hertzbeat-collector/hertzbeat-collector-collector -am -Pnative -DskipTests
```
> 仓库中的 `.github/workflows/collector-native-build.yml` 是 release 辅助工作流,不参与日常 PR 或 push 的常规 CI。
@@ -227,24 +245,27 @@ mvn clean package -pl hertzbeat-collector-collector -am -Pnative
- `dist/apache-hertzbeat-collector-{version}-bin.tar.gz`
- `dist/apache-hertzbeat-collector-native-{version}-linux-amd64-bin.tar.gz`
- `dist/apache-hertzbeat-collector-native-{version}-linux-arm64-bin.tar.gz`
- `dist/apache-hertzbeat-collector-native-{version}-macos-amd64-bin.tar.gz`
- `dist/apache-hertzbeat-collector-native-{version}-macos-arm64-bin.tar.gz`
- `dist/apache-hertzbeat-collector-native-{version}-windows-amd64-bin.zip`
- `dist/apache-hertzbeat-{version}-docker-compose.tar.gz`
> **构建完成后请逐个启动一次 Native 采集器包再进行签名。** Native 包曾出现过构建成功、启动即崩溃的情况,
> 而签名和上传流程都不会发现这一点。解压后执行 `bin/startup.sh`Windows 为 `bin\startup.bat`),
> 确认日志出现 `Started Collector` 和 `Registered N collect strategies`,且进程在十几秒后仍然存活。
#### 3.4 打包项目源代码
> 打包项目源码
```shell
# 注意替换版本号
git archive \
--format=tar.gz \
--output="dist/apache-hertzbeat-1.7.3-src.tar.gz" \
--prefix=apache-hertzbeat-1.7.3-src/ \
release-1.7.3-rc1
--output="dist/apache-hertzbeat-{version}-src.tar.gz" \
--prefix=apache-hertzbeat-{version}-src/ \
release-{version}-rc1
```
生成的代码归档文件在 `dist/apache-hertzbeat-1.7.3-src.tar.gz`
生成的代码归档文件在 `dist/apache-hertzbeat-{version}-src.tar.gz`
### 签名发布物料
@@ -252,35 +273,55 @@ release-1.7.3-rc1
将上步骤生成的三个文件包放到`dist`目录下(若无则新建目录),然后对文件包进行签名和SHA512校验和生成。
> 其中 `gpg -u 33545C76` 的 `33545C76` 是你的 GPG 密钥 ID,可以通过 `gpg --keyid-format SHORT --list-keys` 查看。
> 其中 `<YOUR_KEY_ID>` 是你的 GPG 密钥 ID,可以通过 `gpg --keyid-format SHORT --list-keys` 查看。
```shell
cd dist
# sign
for i in *.tar.gz; do echo $i; gpg -u 33545C76 --armor --output $i.asc --detach-sig $i ; done
# 签名,已有签名的物料会跳过
for i in *.tar.gz *.zip; do
[ -e "$i.asc" ] || { echo "sign: $i"; gpg -u <YOUR_KEY_ID> --armor --output "$i.asc" --detach-sig "$i"; }
done
# SHA512
for i in *.tar.gz; do echo $i; sha512sum $i > $i.sha512 ; done
# SHA512 校验和,已有校验和的物料会跳过
for i in *.tar.gz *.zip; do
[ -e "$i.sha512" ] || { echo "sha512: $i"; sha512sum "$i" > "$i.sha512"; }
done
# if macos sha512sum not found, you can install by brew install coreutils
# macOS 上若提示 sha512sum 不存在,可通过 brew install coreutils 安装
# 完整性自检:每个物料都必须同时有 .asc 和 .sha512
# 通配符漏掉某类物料时(例如只写 *.tar.gz 会漏掉 Windows 的 .zip),这里会立刻发现
for i in *.tar.gz *.zip; do
[ -e "$i.asc" ] || echo "缺少签名: $i"
[ -e "$i.sha512" ] || echo "缺少校验和: $i"
done
```
> 最终文件列表如下
```text
apache-hertzbeat-1.7.3-src.tar.gz
apache-hertzbeat-1.7.3-src.tar.gz.asc
apache-hertzbeat-1.7.3-src.tar.gz.sha512
apache-hertzbeat-1.7.3-bin.tar.gz
apache-hertzbeat-1.7.3-bin.tar.gz.asc
apache-hertzbeat-1.7.3-bin.tar.gz.sha512
apache-hertzbeat-1.7.3-docker-compose.tar.gz
apache-hertzbeat-1.7.3-docker-compose.tar.gz.asc
apache-hertzbeat-1.7.3-docker-compose.tar.gz.sha512
apache-hertzbeat-collector-1.7.3-bin.tar.gz
apache-hertzbeat-collector-1.7.3-bin.tar.gz.asc
apache-hertzbeat-collector-1.7.3-bin.tar.gz.sha512
apache-hertzbeat-{version}-src.tar.gz
apache-hertzbeat-{version}-src.tar.gz.asc
apache-hertzbeat-{version}-src.tar.gz.sha512
apache-hertzbeat-{version}-bin.tar.gz
apache-hertzbeat-{version}-bin.tar.gz.asc
apache-hertzbeat-{version}-bin.tar.gz.sha512
apache-hertzbeat-{version}-docker-compose.tar.gz
apache-hertzbeat-{version}-docker-compose.tar.gz.asc
apache-hertzbeat-{version}-docker-compose.tar.gz.sha512
apache-hertzbeat-collector-{version}-bin.tar.gz
apache-hertzbeat-collector-{version}-bin.tar.gz.asc
apache-hertzbeat-collector-{version}-bin.tar.gz.sha512
apache-hertzbeat-collector-native-{version}-linux-amd64-bin.tar.gz
apache-hertzbeat-collector-native-{version}-linux-amd64-bin.tar.gz.asc
apache-hertzbeat-collector-native-{version}-linux-amd64-bin.tar.gz.sha512
apache-hertzbeat-collector-native-{version}-linux-arm64-bin.tar.gz
apache-hertzbeat-collector-native-{version}-linux-arm64-bin.tar.gz.asc
apache-hertzbeat-collector-native-{version}-linux-arm64-bin.tar.gz.sha512
apache-hertzbeat-collector-native-{version}-windows-amd64-bin.zip
apache-hertzbeat-collector-native-{version}-windows-amd64-bin.zip.asc
apache-hertzbeat-collector-native-{version}-windows-amd64-bin.zip.sha512
```
#### 3.6 验证签名
@@ -289,36 +330,61 @@ apache-hertzbeat-collector-1.7.3-bin.tar.gz.sha512
$ cd dist
# 验证签名
$ for i in *.tar.gz; do echo $i; gpg --verify $i.asc $i ; done
$ for i in *.tar.gz *.zip; do echo $i; gpg --verify $i.asc $i ; done
apache-hertzbeat-1.7.3-bin.tar.gz
gpg: Signature made Tue May 2 12:16:35 2023 CST
gpg: using RSA key 85778A4CE4DD04B7E07813ABACFB69E705016886
gpg: Good signature from "muchunjin (apache key) [muchunjin@apache.org](mailto:muchunjin@apache.org)" [ultimate]
apache-hertzbeat-1.7.3-docker-compose.tar.gz
gpg: Signature made Tue May 2 12:16:36 2023 CST
gpg: using RSA key 85778A4CE4DD04B7E07813ABACFB69E705016886
gpg: Good signature from "muchunjin (apache key) [muchunjin@apache.org](mailto:muchunjin@apache.org)" [ultimate]
apache-hertzbeat-1.7.3-src.tar.gz
gpg: Signature made Tue May 2 12:16:37 2023 CST
gpg: using RSA key 85778A4CE4DD04B7E07813ABACFB69E705016886
gpg: Good signature from "muchunjin (apache key) [muchunjin@apache.org](mailto:muchunjin@apache.org)" [ultimate]
apache-hertzbeat-collector-1.7.3-bin.tar.gz
gpg: Signature made Tue May 2 12:16:37 2023 CST
gpg: using RSA key 85778A4CE4DD04B7E07813ABACFB69E705016886
gpg: Good signature from "muchunjin (apache key) [muchunjin@apache.org](mailto:muchunjin@apache.org)" [ultimate]
apache-hertzbeat-{version}-bin.tar.gz
gpg: Signature made Sun Sep 13 06:59:54 2026 PDT
gpg: using RSA key C787268D3396367EB3C2242402CA7E2CEF04C474
gpg: Good signature from "duansg <duansg@apache.org>" [ultimate]
apache-hertzbeat-{version}-docker-bin.tar.gz
gpg: Signature made Sun Sep 13 07:00:39 2026 PDT
gpg: using RSA key C787268D3396367EB3C2242402CA7E2CEF04C474
gpg: Good signature from "duansg <duansg@apache.org>" [ultimate]
apache-hertzbeat-{version}-docker-compose.tar.gz
gpg: Signature made Sun Sep 13 07:00:39 2026 PDT
gpg: using RSA key C787268D3396367EB3C2242402CA7E2CEF04C474
gpg: Good signature from "duansg <duansg@apache.org>" [ultimate]
apache-hertzbeat-{version}-src.tar.gz
gpg: Signature made Sun Sep 13 07:00:39 2026 PDT
gpg: using RSA key C787268D3396367EB3C2242402CA7E2CEF04C474
gpg: Good signature from "duansg <duansg@apache.org>" [ultimate]
apache-hertzbeat-collector-{version}-bin.tar.gz
gpg: Signature made Sun Sep 13 07:00:40 2026 PDT
gpg: using RSA key C787268D3396367EB3C2242402CA7E2CEF04C474
gpg: Good signature from "duansg <duansg@apache.org>" [ultimate]
apache-hertzbeat-collector-native-{version}-linux-amd64-bin.tar.gz
gpg: Signature made Sun Sep 13 07:00:41 2026 PDT
gpg: using RSA key C787268D3396367EB3C2242402CA7E2CEF04C474
gpg: Good signature from "duansg <duansg@apache.org>" [ultimate]
apache-hertzbeat-collector-native-{version}-linux-arm64-bin.tar.gz
gpg: Signature made Sun Sep 13 07:00:41 2026 PDT
gpg: using RSA key C787268D3396367EB3C2242402CA7E2CEF04C474
gpg: Good signature from "duansg <duansg@apache.org>" [ultimate]
apache-hertzbeat-collector-native-{version}-windows-amd64-bin.zip
gpg: Signature made Sun Sep 13 18:42:45 2026 PDT
gpg: using RSA key C787268D3396367EB3C2242402CA7E2CEF04C474
gpg: Good signature from "duansg <duansg@apache.org>" [ultimate]
# 验证 SHA512
$ for i in *.tar.gz; do echo $i; sha512sum --check $i.sha512; done
$ for i in *.tar.gz *.zip; do echo $i; sha512sum --check $i.sha512; done
apache-hertzbeat-1.7.3-src.tar.gz
apache-hertzbeat-1.7.3-src.tar.gz: OK
apache-hertzbeat-1.7.3-bin.tar.gz
apache-hertzbeat-1.7.3-bin.tar.gz: OK
apache-hertzbeat-1.7.3-docker-compose.tar.gz
apache-hertzbeat-1.7.3-docker-compose.tar.gz: OK
apache-hertzbeat-collector-1.7.3-bin.tar.gz
apache-hertzbeat-collector-1.7.3-bin.tar.gz: OK
apache-hertzbeat-{version}-bin.tar.gz
apache-hertzbeat-{version}-bin.tar.gz: OK
apache-hertzbeat-{version}-docker-bin.tar.gz
apache-hertzbeat-{version}-docker-bin.tar.gz: OK
apache-hertzbeat-{version}-docker-compose.tar.gz
apache-hertzbeat-{version}-docker-compose.tar.gz: OK
apache-hertzbeat-{version}-src.tar.gz
apache-hertzbeat-{version}-src.tar.gz: OK
apache-hertzbeat-collector-{version}-bin.tar.gz
apache-hertzbeat-collector-{version}-bin.tar.gz: OK
apache-hertzbeat-collector-native-{version}-linux-amd64-bin.tar.gz
apache-hertzbeat-collector-native-{version}-linux-amd64-bin.tar.gz: OK
apache-hertzbeat-collector-native-{version}-linux-arm64-bin.tar.gz
apache-hertzbeat-collector-native-{version}-linux-arm64-bin.tar.gz: OK
apache-hertzbeat-collector-native-{version}-windows-amd64-bin.zip
apache-hertzbeat-collector-native-{version}-windows-amd64-bin.zip: OK
```
#### 3.7 发布 Apache SVN 仓库中 dev 目录的物料包
@@ -326,19 +392,20 @@ apache-hertzbeat-collector-1.7.3-bin.tar.gz: OK
- 检出仓库
```shell
# 检出 Apache SVN 仓库中的 dev/incubator/hertzbeat 目录到 Apache HertzBeat™ 项目根目录下的 svn/dev 目录下
# 检出 Apache SVN 仓库中的 dev/hertzbeat 目录到 Apache HertzBeat™ 项目根目录下的 svn/dev 目录下
svn co https://dist.apache.org/repos/dist/dev/hertzbeat svn/dev
svn co --depth empty https://dist.apache.org/repos/dist/dev/hertzbeat
# 历史候选版本较多时,可改用空检出,避免下载全部历史物料
# svn co --depth empty https://dist.apache.org/repos/dist/dev/hertzbeat svn/dev
```
- 复制物料包到 SVN 仓库
创建一个版本号目录,并以`release_version`-`RC_version`的形式命名。RC_version从1开始,即候选版本从RC1开始。在发布过程中,如果出现导致投票失败的问题,需要进行修正,那么RC版本需要迭代,RC版本号需要+1。例如:为版本1.7.3-RC1投票。如果投票顺利通过,那么RC1版本的资料将作为最终版本的资料发布。如果出现问题并需要纠正,那么修正后重新启动投票,下一次的候选版本为1.7.3-RC2。
创建一个版本号目录,并以`release_version`-`RC_version`的形式命名。RC_version从1开始,即候选版本从RC1开始。在发布过程中,如果出现导致投票失败的问题,需要进行修正,那么RC版本需要迭代,RC版本号需要+1。例如:为版本 `{version}-RC1` 投票。如果投票顺利通过,那么RC1版本的资料将作为最终版本的资料发布。如果出现问题并需要纠正,那么修正后重新启动投票,下一次的候选版本为 `{version}-RC2`
```shell
mkdir -p svn/dev/1.7.3-RC1
cp -f dist/* svn/dev/1.7.3-RC1
mkdir -p svn/dev/{version}-RC1
cp -f dist/* svn/dev/{version}-RC1
```
- 提交到SVN
@@ -350,12 +417,12 @@ cd svn/dev
svn status
# 2. 添加到svn
svn add 1.7.3-RC1
svn add {version}-RC1
svn status
# 3. 提交到svn远端服务器
svn commit -m "release for HertzBeat 1.7.3-RC1"
svn commit -m "release for HertzBeat {version}-RC1"
```
- 检查 Apache SVN 提交结果
@@ -368,27 +435,33 @@ svn commit -m "release for HertzBeat 1.7.3-RC1"
发送社区投票邮件需要至少三个`+1`,且无`-1`
:::caution 发信前先确认两件事
1. **你的公钥已经在 KEYS 文件里**:访问 [https://downloads.apache.org/hertzbeat/KEYS](https://downloads.apache.org/hertzbeat/KEYS) 搜索自己的邮箱,找不到则投票者无法验证签名。KEYS 的添加见 2.4。
2. **模板里的版本号和 RC 号已全部替换**:下面的模板共有 **5 处**需要改动——邮件标题、正文第一行、Release notes 链接、候选物料链接、Git tag 链接。RC 号递增时(RC1 → RC2)这几处必须同步修改,漏改任何一处都会让投票者困惑。
:::
> `Send to`: [dev@hertzbeat.apache.org](mailto:dev@hertzbeat.apache.org) <br />
> `Title`: [VOTE] Release Apache HertzBeat 1.7.3 rc1 <br />
> `Title`: `[VOTE] Release Apache HertzBeat {version} rc1` <br />
> `Body`:
```text
Hello HertzBeat Community:
This is a call for vote to release Apache HertzBeat version release-1.7.3-RC1.
This is a call for vote to release Apache HertzBeat version release-{version}-RC1.
Apache HertzBeat - a real-time observability system with agentless, performance cluster, prometheus-compatible, custom monitoring and status page building capabilities.
Release notes:
https://github.com/apache/hertzbeat/releases/tag/v1.7.3-rc1
https://github.com/apache/hertzbeat/releases/tag/v{version}-rc1
The release candidates:
https://dist.apache.org/repos/dist/dev/hertzbeat/1.7.3-RC1/
https://dist.apache.org/repos/dist/dev/hertzbeat/{version}-RC1/
Git tag for the release:
https://github.com/apache/hertzbeat/releases/tag/v1.7.3-rc1
https://github.com/apache/hertzbeat/releases/tag/v{version}-rc1
The artifacts signed with PGP key [33545C76], corresponding to [muchunjin@apache.org], that can be found in keys file:
The artifacts signed with PGP key [<YOUR_KEY_ID>], corresponding to [<YOUR_APACHE_ID>@apache.org], that can be found in keys file:
https://downloads.apache.org/hertzbeat/KEYS
The vote will be open for at least 72 hours or until the necessary number of votes are reached.
@@ -422,13 +495,13 @@ Thanks!
在72小时后,将统计投票结果,并发送投票结果邮件,如下所示。
> `Send to`: [dev@hertzbeat.apache.org](mailto:dev@hertzbeat.apache.org) <br />
> `Title`: [RESULT]\[VOTE\] Release Apache HertzBeat 1.7.3-rc1 <br />
> `Title`: `[RESULT][VOTE] Release Apache HertzBeat {version}-rc1` <br />
> `Body`:
```text
Dear HertzBeat community,
Thanks for your review and vote for "Release Apache HertzBeat 1.7.3-rc1"
Thanks for your review and vote for "Release Apache HertzBeat {version}-rc1"
I'm happy to announce the vote has passed:
---
4 binding +1, from:
@@ -447,20 +520,20 @@ https://lists.apache.org/thread/t01b2lbtqzyt7j4dsbdp5qjc3gngjsdq
Thank you to everyone who helped us to verify and vote for this release.
---
Best,
ChunJin Mu
<YOUR_NAME>
```
邮件内容中的一项是`Vote thread`,在 [https://lists.apache.org/list.html?dev@hertzbeat.apache.org](https://lists.apache.org/list.html?dev@hertzbeat.apache.org) 查看获取
## 4. 完成最终发布步骤
## 5. 完成最终发布步骤
### 4.1 迁移源代码和二进制包
### 5.1 迁移源代码和二进制包
```shell
svn mv https://dist.apache.org/repos/dist/dev/hertzbeat/1.7.3-RC1 https://dist.apache.org/repos/dist/release/hertzbeat/1.7.3 -m "transfer packages for 1.7.3-RC1"
svn mv https://dist.apache.org/repos/dist/dev/hertzbeat/{version}-RC1 https://dist.apache.org/repos/dist/release/hertzbeat/{version} -m "transfer packages for {version}-RC1"
```
### 4.2 添加新版本下载地址到官网
### 5.2 添加新版本下载地址到官网
[https://github.com/apache/hertzbeat/blob/master/home/docs/download.md](https://github.com/apache/hertzbeat/blob/master/home/docs/download.md)
[https://github.com/apache/hertzbeat/blob/master/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/download.md](https://github.com/apache/hertzbeat/blob/master/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/download.md)
@@ -469,9 +542,9 @@ svn mv https://dist.apache.org/repos/dist/dev/hertzbeat/1.7.3-RC1 https://dist.a
> 需要注意的是,下载链接可能需要一个小时后才会生效,请注意。
### 4.3 Github 生成 Release
### 5.3 Github 生成 Release
基于 release-1.7.3-rc1 分支修改创建一个名为 v1.7.3 的标签,并将此标签设置为 latest release。
基于 `release-{version}-rc1` 分支修改创建一个名为 `v{version}` 的标签,并将此标签设置为 latest release。
:::tip
在原有的 Release 上面修改,无需重新创建 Release。
@@ -482,7 +555,7 @@ svn mv https://dist.apache.org/repos/dist/dev/hertzbeat/1.7.3-RC1 https://dist.a
- 发版标题:
```text
v1.7.3
v{version}
```
- 描述:
@@ -494,19 +567,19 @@ release note: xxx
然后点击`Publish release`按钮。
然后将 release-1.7.3-rc1 分支重命名 为 release-1.7.3
然后将 `release-{version}-rc1` 分支重命名为 `release-{version}`
### 4.4 发送新版本公告邮件
### 5.4 发送新版本公告邮件
> `Send to`: [announce@apache.org](mailto:announce@apache.org) <br />
> `cc`: [dev@hertzbeat.apache.org](mailto:dev@hertzbeat.apache.org) <br />
> `Title`: [ANNOUNCE] Apache HertzBeat 1.7.3 released <br />
> `Title`: `[ANNOUNCE] Apache HertzBeat {version} released` <br />
> `Body`:
```text
Hi Community,
We are glad to announce the release of Apache HertzBeat 1.7.3.
We are glad to announce the release of Apache HertzBeat {version}.
Thanks again for your help.
Apache HertzBeat (https://hertzbeat.apache.org/) - a real-time observability system with agentless, performance cluster, prometheus-compatible, custom monitoring and status page building capabilities.
@@ -515,7 +588,7 @@ Download Link:
https://hertzbeat.apache.org/docs/download/
Release Note:
https://github.com/apache/hertzbeat/releases/tag/v1.7.3
https://github.com/apache/hertzbeat/releases/tag/v{version}
Website:
https://hertzbeat.apache.org/
@@ -527,11 +600,9 @@ HertzBeat Resources:
Apache HertzBeat Team
Best,
ChunJin Mu
<YOUR_NAME>
```
该版本的发布顺利结束。
---
This doc refer from [Apache StreamPark](https://streampark.apache.org/)
@@ -6,7 +6,7 @@ sidebar_position: 4
## 验证候选版本
详细检查列表请参考官方的[check list](https://cwiki.apache.org/confluence/display/INCUBATOR/Incubator+Release+Checklist)
详细检查列表请参考 ASF 官方的[发布策略](https://www.apache.org/legal/release-policy.html)与[发布检查清单](https://infra.apache.org/release-publishing.html)
在浏览器中可访问版本内容 [https://dist.apache.org/repos/dist/dev/hertzbeat/](https://dist.apache.org/repos/dist/dev/hertzbeat/)
@@ -15,10 +15,13 @@ sidebar_position: 4
> 需要依赖gpg工具,如果没有,建议安装gpg2
```shell
#如果本地有svn,可以clone到本地
svn co https://dist.apache.org/repos/dist/dev/hertzbeat/`release_version`-`rc_version`/
#或者 直接下载物料文件
wget https://dist.apache.org/repos/dist/dev/hertzbeat/`release_version`-`rc_version`/xxx.xxx
# 将 {version} 与 RC1 替换为本次投票的版本号和候选版本号,例如 1.9.0 与 RC2
# 如果本地有 svn,可以整个目录检出
svn co https://dist.apache.org/repos/dist/dev/hertzbeat/{version}-RC1/
# 或者直接下载单个物料文件
wget https://dist.apache.org/repos/dist/dev/hertzbeat/{version}-RC1/apache-hertzbeat-{version}-src.tar.gz
```
@@ -33,7 +36,17 @@ wget https://dist.apache.org/repos/dist/dev/hertzbeat/`release_version`-`rc_vers
1. 是否包含源码包
2. 是否包含源码包的签名
3. 是否包含源码包的sha512
4. 如果上传了二进制包,则同样检查(2)-(4)所列的内容
4. 如果上传了二进制包(含 native 采集器包),则每个包同样检查第 2、3 项
> **每一个**物料都必须有对应的 `.asc` 和 `.sha512`,一个都不能少。可以用下面的命令快速核对,
> 有输出就说明有物料缺失:
>
> ```shell
> for i in *.tar.gz *.zip; do
> [ -e "$i.asc" ] || echo "缺少签名: $i"
> [ -e "$i.sha512" ] || echo "缺少校验和: $i"
> done
> ```
#### 2.2 检查gpg签名
@@ -46,9 +59,22 @@ curl https://downloads.apache.org/hertzbeat/KEYS > KEYS # 下载KEYS
gpg --import KEYS # 导入KEYS到本地
```
##### 2.2.2 信任公钥
##### 2.2.2 关于信任公钥
> 信任此次版本所使用的KEY
:::tip 验证签名并不需要信任公钥
`gpg --verify` 对未信任的公钥同样会输出 `Good signature`,只是会附带一行提示:
```text
WARNING: This key is not certified with a trusted signature!
```
**这行 WARNING 是正常的,只要出现 `Good signature` 即视为通过。**
如果你确实想消除这个提示,可以按下面的方式设置信任级别。但请注意,`5 = ultimate` 在 GPG 语义中表示
“这是我自己的密钥”,把他人的公钥设为 ultimate 会污染本地信任网,一般选择 `4 = fully` 更合适。
:::
> 设置此次版本所使用 KEY 的信任级别(可选)
```shell
$ gpg --edit-key xxxxxxxxxx #此次版本所使用的KEY用户
@@ -78,9 +104,14 @@ gpg>
##### 2.2.3 检查签名
```shell
for i in *.tar.gz; do echo $i; gpg --verify $i.asc $i ; done
# 注意同时覆盖 *.zipWindows 的 native 采集器包是 zip 格式,
# 只写 *.tar.gz 会静默跳过它
for i in *.tar.gz *.zip; do echo $i; gpg --verify $i.asc $i ; done
```
> 核对签名所用的 key 与投票邮件中声明的 PGP key ID 是否一致。只有 `Good signature` 而 key 对不上,
> 并不能说明物料是发布者签的。
检查结果
> 出现类似以下内容则说明签名正确,关键字:**`Good signature`**
@@ -97,9 +128,18 @@ gpg: Good signature from "XXX <xxx@apache.org>"
> 本地计算sha512哈希后,验证是否与dist上的一致,如果上传二进制包,则同样需要检查二进制包的sha512哈希
```shell
for i in *.tar.gz; do echo $i; sha512sum --check $i.sha512; done
for i in *.tar.gz *.zip; do echo $i; sha512sum --check "$i.sha512"; done
# macOS 上如果没有 sha512sum,可用系统自带的 shasum 替代
# for i in *.tar.gz *.zip; do echo $i; shasum -a 512 -c "$i.sha512"; done
```
> 每个物料输出 `OK` 即为通过:
>
> ```text
> apache-hertzbeat-{version}-src.tar.gz: OK
> ```
#### 2.4 检查二进制包
解压缩 `apache-hertzbeat-${release_version}-bin.tar.gz`
@@ -121,7 +161,37 @@ tar -xzvf apache-hertzbeat-${release_version}-bin.tar.gz
参考: [https://apache.org/legal/resolved.html](https://apache.org/legal/resolved.html)
#### 2.5. 源码编译验证
#### 2.5 检查 Native 采集器包
Native 采集器包(`apache-hertzbeat-collector-native-{version}-*`)是**预编译的原生可执行文件**
不适用下面的“源码编译验证”,需要单独检查。
```shell
tar -xzf apache-hertzbeat-collector-native-{version}-linux-amd64-bin.tar.gz
cd apache-hertzbeat-collector-native-{version}-linux-amd64-bin
MANAGER_HOST=127.0.0.1 ./bin/startup.sh
tail -f logs/startup.log
```
进行如下检查:
- [ ] 存在 `LICENSE``NOTICE``licenses/` 目录
- [ ] 能够正常启动:日志出现 `Started Collector``Registered N collect strategies`
- [ ] 启动十几秒后进程仍然存活(**崩溃可能发生在 `Started Collector` 之后**,只看这一行不够)
:::caution Native 包有硬性运行环境要求
不满足时的表现是**进程瞬间退出、没有任何日志输出**,很容易被误判为物料损坏。遇到这种情况请先确认环境:
- **x86 包需要 CPU 支持 AVX2**Intel Haswell2013)及以后、AMD Zen2017)及以后。部分 Atom 血统的低端芯片、
Apple Silicon 上的 Rosetta 2、旧版 Windows on ARM 模拟均不支持
- **Linux 包需要 glibc ≥ 2.34**Ubuntu 22.04+、Debian 12+、RHEL/Rocky 9+ 可用;
Ubuntu 20.04、Debian 11、RHEL 8、CentOS 7 不可用
- **Windows 包需要** Windows 10 / Server 2016 及以上,并安装 Microsoft Visual C++ 2015-2022 可再发行组件包
环境不满足属于已知限制,不应据此投 -1;请在回复中说明你的验证环境。
:::
#### 2.6 源码编译验证
解压缩 `apache-hertzbeat-${release_version}-src.tar.gz`
@@ -156,28 +226,43 @@ PMC 在 [dev@hertzbeat.apache.org](mailto:dev@hertzbeat.apache.org) HertzBeat
非PMC成员
```html
```text
+1 (non-binding)
I checked:
I checked:
1. All download links are valid
2. Checksum and signature are OK
3. LICENSE and NOTICE are exist
4. Build successfully on macOS(Big Sur)
5. ....
2. Checksums and signatures are OK for all artifacts, including the .zip
3. LICENSE and NOTICE exist and are correct
4. Built successfully from source on <你的操作系统和版本>
5. Native collector package starts and registers its collect strategies
6. ....
```
PMC成员
```html
```text
+1 (binding)
I checked:
I checked:
1. All download links are valid
2. Checksum and signature are OK
3. LICENSE and NOTICE are exist
4. Build successfully on macOS(Big Sur)
5. ....
2. Checksums and signatures are OK for all artifacts, including the .zip
3. LICENSE and NOTICE exist and are correct
4. Built successfully from source on <你的操作系统和版本>
5. Native collector package starts and registers its collect strategies
6. ....
```
发现问题时,请给出具体的复现信息,便于发布者定位:
```text
-1 (binding)
The <物料名> is missing its .sha512 checksum.
Checked on: macOS 26 / arm64
Steps:
1. svn co https://dist.apache.org/repos/dist/dev/hertzbeat/1.9.0-RC2/
2. for i in *.tar.gz *.zip; do [ -e "$i.sha512" ] || echo "missing: $i"; done
Output:
missing: apache-hertzbeat-collector-native-1.9.0-windows-amd64-bin.zip
```
---
This doc refer from [Apache StreamPark](https://streampark.apache.org/)
@@ -33,6 +33,40 @@ Native 采集器并不是所有 JVM 采集器场景的无损替代。
- Native 采集器不支持在运行时从 `ext-lib` 目录动态加载外部 JDBC 驱动 JAR。
- 如果你的部署依赖 JVM 风格的运行时 classpath 扩展能力,仍然应该使用 JVM 采集器安装包。
## 运行环境要求
Native 采集器是提前编译好的原生可执行文件,运行环境的要求比 JVM 采集器**严格得多**。JVM 采集器由 JIT 在
启动时探测 CPU 特性并自动适配,而 native 包在构建时就把指令集固化进了二进制,没有回退机制。
| 平台 | 要求 |
| --- | --- |
| Linux / Windowsx86-64 | CPU 必须支持 **AVX2**Intel Haswell2013)及以后、AMD Zen2017)及以后 |
| Linux(两种架构) | **glibc ≥ 2.34** |
| Linuxarm64 | ARMv8-A 基线即可,无额外指令集要求 |
| Windows | Windows 10 / Server 2016 及以上,并安装 **Microsoft Visual C++ 2015-2022 可再发行组件包** |
常见发行版对照(glibc ≥ 2.34 这条线):
| 可用 | 不可用 |
| --- | --- |
| Ubuntu 22.04 / 24.04、Debian 12、RHEL / Rocky / AlmaLinux 9、Amazon Linux 2023 | Ubuntu 20.04、Debian 11、RHEL / Rocky / AlmaLinux 8、CentOS 7、Amazon Linux 2 |
不支持 AVX2 的环境还包括:部分 Atom 血统的低端芯片(如 J4125、N4020、N5105)、Apple Silicon 上的
Rosetta 2、以及未更新到 Prism 新版模拟器的 Windows on ARM。
:::caution 不满足要求时的表现很具有迷惑性
- **CPU 不支持 AVX2**:进程**瞬间退出,没有任何输出、也没有日志文件**(Linux 上报 `Illegal instruction`
Windows 上退出码为 `-1073741795`
- **glibc 版本过低**:报 `version 'GLIBC_2.34' not found`
- **Windows 缺少 VC++ 运行库**:报缺少 `VCRUNTIME140_1.dll`
第一种最容易被误判为"安装包损坏"。遇到"双击没反应"或"启动了什么都没打印"时,请先核对 CPU 是否支持 AVX2。
**任何一项不满足,都可以改用 JVM 采集器安装包** `apache-hertzbeat-collector-{version}-bin.tar.gz`
它只要求 JDK 25,没有上述限制。
:::
## 哪些场景应该继续使用 JVM 采集器?
如果你的监控依赖外部 JDBC 驱动,请继续使用 JVM 采集器安装包,尤其包括:
@@ -54,9 +88,9 @@ Native 采集器安装包按平台区分:
例如:
- `apache-hertzbeat-collector-native-1.8.0-linux-amd64-bin.tar.gz`
- `apache-hertzbeat-collector-native-1.8.0-macos-arm64-bin.tar.gz`
- `apache-hertzbeat-collector-native-1.8.0-windows-amd64-bin.zip`
- `apache-hertzbeat-collector-native-1.9.0-linux-amd64-bin.tar.gz`
- `apache-hertzbeat-collector-native-1.9.0-macos-arm64-bin.tar.gz`
- `apache-hertzbeat-collector-native-1.9.0-windows-amd64-bin.zip`
## 配置文件是否和 JVM 采集器一致?
@@ -14,6 +14,16 @@ HertzBeat 的元数据信息保存在 H2 或 Mysql, PostgreSQL 关系型数据
**升级前您需要保存备份好数据库的数据文件和监控模板文件**
## 1.9.0 新增:Native 采集器安装包
1.9.0 起提供预编译的 Native 采集器安装包(`apache-hertzbeat-collector-native-*`),启动快、内存占用低。
它**不是 JVM 采集器的无损替代**,且对运行环境有硬性要求(x86 包需要 CPU 支持 AVX2、Linux 包需要
glibc ≥ 2.34、Windows 包需要 VC++ 运行库),不满足时进程会**瞬间退出且没有任何日志**。
升级时如果打算改用 Native 采集器,请先阅读 [Native 采集器](native-collector) 中的"运行环境要求"。
原有的 JVM 采集器安装包 `apache-hertzbeat-collector-{version}-bin.tar.gz` 继续提供,升级方式不变。
## 1.9.0 不兼容变更
### SFTP监控必须显式配置主机密钥策略
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB