简介
在部署和运行 Optimism 的过程中,手动启动各个组件既繁琐又容易出错。本文将详细介绍如何使用 systemd 服务来自动化管理 OP Stack 的各个核心组件,包括 op-geth、op-node、op-batcher 和 op-proposer。
⚠️本文中的路径 /home/eth/optimism/ 仅作示例,使用前请根据自己的部署目录修改
一、Why Systemd?
Systemd 是现代 Linux 发行版的标准初始化系统和服务管理器,它提供了以下优势:
- 自动重启:当服务异常退出时自动重启
- 依赖管理:确保服务按正确顺序启动
- 日志管理:集中管理服务日志
- 开机自启:系统重启后自动启动服务
二、启动脚本
2.1 创建脚本目录
1 2 3
| cd ~/optimism/ mkdir -p scripts cd scripts/
|
2.2 创建启动脚本
OP-Geth 启动脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| cat > ./op-geth_starter.sh << 'EOF'
LOG_DIR="/home/eth/optimism/logs/op-geth" mkdir -p $LOG_DIR
echo "Starting Geth node at $(date)" cd /home/eth/optimism/op-geth
source /home/eth/optimism/.envrc
exec ./build/bin/geth \ --datadir ./datadir \ --http \ --http.corsdomain="*" \ --http.vhosts="*" \ --http.addr=0.0.0.0 \ --http.api=web3,debug,eth,txpool,net,engine,miner \ --ws \ --ws.addr=0.0.0.0 \ --ws.port=8546 \ --ws.origins="*" \ --ws.api=debug,eth,txpool,net,engine,miner \ --syncmode=full \ --gcmode=archive \ --nodiscover \ --maxpeers=0 \ --networkid=$L2_CHAIN_ID \ --authrpc.vhosts="*" \ --authrpc.addr=0.0.0.0 \ --authrpc.port=8551 \ --authrpc.jwtsecret=./jwt.txt \ --rollup.disabletxpoolgossip=true EOF
|
OP-Node 启动脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| cat > ./op-node_starter.sh << 'EOF'
LOG_DIR="/home/eth/optimism/logs/op-node" mkdir -p $LOG_DIR
echo "Starting OP-Node at $(date)" cd /home/eth/optimism/op-node
source /home/eth/optimism/.envrc
exec ./bin/op-node \ --l2=http://localhost:8551 \ --l2.jwt-secret=./jwt.txt \ --sequencer.enabled \ --sequencer.l1-confs=5 \ --verifier.l1-confs=4 \ --rollup.config=../.deployer/rollup.json \ --rpc.addr=0.0.0.0 \ --rpc.port=9545 \ --p2p.disable \ --rpc.enable-admin \ --p2p.sequencer.key=$GS_SEQUENCER_PRIVATE_KEY \ --l1=$L1_RPC_URL \ --l1.rpckind=$L1_RPC_KIND \ --l1.beacon=$L1_BEACON_URL EOF
|
OP-Batcher 启动脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| cat > ./op-batcher_starter.sh << 'EOF'
LOG_DIR="/home/eth/optimism/logs/op-batcher" mkdir -p $LOG_DIR
echo "Starting OP-Batcher at $(date)" cd /home/eth/optimism/op-batcher
source /home/eth/optimism/.envrc
exec ./bin/op-batcher \ --l2-eth-rpc=http://localhost:8545 \ --rollup-rpc=http://localhost:9545 \ --poll-interval=1s \ --sub-safety-margin=6 \ --num-confirmations=1 \ --safe-abort-nonce-too-low-count=3 \ --resubmission-timeout=30s \ --rpc.addr=0.0.0.0 \ --rpc.port=8548 \ --rpc.enable-admin \ --max-channel-duration=25 \ --l1-eth-rpc=$L1_RPC_URL \ --private-key=$GS_BATCHER_PRIVATE_KEY EOF
|
OP-Proposer 启动脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| cat > ./op-proposer_starter.sh << 'EOF'
LOG_DIR="/home/eth/optimism/logs/op-proposer" mkdir -p $LOG_DIR
echo "Starting OP-Proposer at $(date)" cd /home/eth/optimism/op-proposer
source /home/eth/optimism/.envrc
exec ./bin/op-proposer \ --poll-interval=12s \ --rpc.port=8560 \ --rollup-rpc=http://localhost:9545 \ --private-key=$GS_PROPOSER_PRIVATE_KEY \ --l1-eth-rpc=$L1_RPC_URL EOF
|
2.3 设置脚本权限
1
| chmod +x op-geth_starter.sh op-node_starter.sh op-batcher_starter.sh op-proposer_starter.sh
|
2.4 测试脚本
此时可以尝试启动一下脚本,检查脚本是否正常工作
1 2 3 4 5 6 7 8 9 10 11
| ./op-geth_starter.sh
./op-node_starter.sh
./op-batcher_starter.sh
./op-proposer_starter.sh
|
三、Systemd 服务文件
3.1 创建服务文件目录
1 2 3
| cd ~/optimism/ mkdir -p service cd service/
|
3.2 创建 Systemd 服务文件
OP-Geth 服务配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| cat > ./op-geth.service << 'EOF' [Unit] Description=OP-Geth Execution Client After=network-online.target Wants=network-online.target
[Service] Type=simple User=root Group=root
WorkingDirectory=/home/eth/optimism/scripts ExecStart=/home/eth/optimism/scripts/op-geth_starter.sh
StandardOutput=append:/home/eth/optimism/logs/op-geth/geth.log StandardError=append:/home/eth/optimism/logs/op-geth/geth.log
Restart=always RestartSec=10 LimitNOFILE=65536
[Install] WantedBy=multi-user.target EOF
|
OP-Node 服务配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| cat > ./op-node.service << 'EOF' [Unit] Description=OP-Node L2 Consensus Client After=network-online.target op-geth.service Wants=network-online.target Requires=op-geth.service
[Service] Type=simple User=root Group=root
WorkingDirectory=/home/eth/optimism/scripts ExecStart=/home/eth/optimism/scripts/op-node_starter.sh
StandardOutput=append:/home/eth/optimism/logs/op-node/op-node.log StandardError=append:/home/eth/optimism/logs/op-node/op-node.log
Restart=always RestartSec=10
[Install] WantedBy=multi-user.target EOF
|
OP-Batcher 服务配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| cat > ./op-batcher.service << 'EOF' [Unit] Description=OP-Batcher L2 Transaction Batcher After=network-online.target op-node.service Wants=network-online.target Requires=op-node.service
[Service] Type=simple User=root Group=root
WorkingDirectory=/home/eth/optimism/scripts ExecStart=/home/eth/optimism/scripts/op-batcher_starter.sh
StandardOutput=append:/home/eth/optimism/logs/op-batcher/op-batcher.log StandardError=append:/home/eth/optimism/logs/op-batcher/op-batcher.log
Restart=always RestartSec=10
[Install] WantedBy=multi-user.target EOF
|
OP-Proposer 服务配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| cat > ./op-proposer.service << 'EOF' [Unit] Description=OP-Proposer L2 State Proposer After=network-online.target op-node.service Wants=network-online.target Requires=op-node.service
[Service] Type=simple User=root Group=root
WorkingDirectory=/home/eth/optimism/scripts ExecStart=/home/eth/optimism/scripts/op-proposer_starter.sh
StandardOutput=append:/home/eth/optimism/logs/op-proposer/op-proposer.log StandardError=append:/home/eth/optimism/logs/op-proposer/op-proposer.log
Restart=always RestartSec=10
[Install] WantedBy=multi-user.target EOF
|
服务依赖关系说明
服务启动的依赖顺序如下:
- op-geth:基础执行客户端,必须首先启动
- op-node:依赖 op-geth 提供的 Engine API
- op-batcher 和 op-proposer:都依赖 op-node 提供的 Rollup RPC
通过 After 和 Requires 指令,systemd 会自动处理这些依赖关系。
3.3 安装服务文件
1 2 3 4 5 6 7 8 9 10 11
| sudo ln -sf /home/eth/optimism/service/*.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemd-analyze verify /etc/systemd/system/${service}.service
sudo systemctl enable op-geth op-node op-batcher op-proposer
|
四、启动服务
1 2 3 4 5
| sudo systemctl start op-geth op-node op-batcher op-proposer
sudo systemctl status op-geth op-node op-batcher op-proposer
|
启动成功状态应如下图所示:

Hooray!Systemd 配置成功!!!
五、常见故障排查
日志管理
OP-Geth: /home/eth/optimism/logs/op-geth/geth.log
OP-Node: /home/eth/optimism/logs/op-node/op-node.log
OP-Batcher: /home/eth/optimism/logs/op-batcher/op-batcher.log
OP-Proposer: /home/eth/optimism/logs/op-proposer/op-proposer.log
5.1 code=exited, status=1/FAILURE
进入的 logs 的路径通过命令 tail -n 50 YOUR_LOG_NAME 查看服务的最近日志,使用 systemd 执行脚本时不会自动加载环境变量,如果脚本中使用了环境变量但没有正确加载,就会导致找不到相关变量而报错。

解决方案:确保启动脚本中正确配置环境变量加载语句:
1
| source ~/optimism/.envrc
|
5.2 code=exited, status=209/STDOUT
通过命令 sudo journalctl -u YOUR_SERVICE_NAME -n 50 --no-pager查看服务的最近日志。服务启动时会检查配置的路径是否可访问或存在,需要检查配置的路径是否存在以及是否具有访问权限。
排查步骤:
- 检查
WorkingDirectory 路径是否存在
- 检查
ExecStart 指向的脚本文件是否存在且有执行权限
- 检查日志目录是否可写

5.3 其他常用调试命令示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| sudo journalctl -u op-geth -f
tail -f op-geth
sudo systemctl restart op-geth op-node op-batcher op-proposer
sudo systemctl stop op-geth op-node op-batcher op-proposer
sudo systemctl is-active op-geth op-node op-batcher op-proposer
|
六、总结
通过使用 systemd 管理 OP Stack 组件,我们实现了:
- 自动化管理:服务自动启动、重启和监控
- 依赖管理:确保服务按正确顺序启动
- 日志集中管理:方便问题排查和监控
- 生产环境就绪:满足生产环境的稳定性要求
这种配置方式特别适合生产环境部署,能够显著减少手动维护工作量,提高系统的可靠性和稳定性。当遇到问题时,通过查看具体的错误代码和日志,能够快速定位和解决问题。