杰瑞科技汇

Java Service Wrapper如何实现服务守护?

Of course! The term "Java Service Wrapper" can refer to two main things, which are often confused:

Java Service Wrapper如何实现服务守护?-图1
(图片来源网络,侵删)
  1. A Generic Concept: The idea of creating a Java application that runs as a background service or daemon on an operating system (like a Windows Service or a Linux systemd service).
  2. A Specific Product: A well-known, third-party library called "Java Service Wrapper" (often abbreviated as jsvc or just "the Wrapper") that helps you achieve this.

I'll cover both, starting with the specific product as it's the most common meaning of the phrase.


The Specific Product: TanukiSoftware Java Service Wrapper

This is a powerful, cross-platform solution for turning your Java application into a native system service or daemon. It's a small native executable that acts as an intermediary between your operating system and your Java Virtual Machine (JVM).

What is it and Why Use It?

The Wrapper is not just a simple script launcher. It's a robust management tool that solves common problems associated with running Java apps as services:

Problem How the Wrapper Solves It
Application Crashes The Wrapper monitors your Java application. If it crashes (e.g., an uncaught OutOfMemoryError), the Wrapper can automatically restart it, ensuring high availability.
Graceful Shutdown When the system is shutting down (e.g., systemctl stop myapp or net stop myapp), the Wrapper can forward this signal to your Java application, allowing you to perform clean-up tasks like closing database connections or saving state.
Console Interaction It allows you to interact with your service using standard system commands (start, stop, status, restart) without needing to be at the console where it was launched.
Logging It provides a robust logging mechanism. It can capture both stdout and stderr from your JVM and write it to a configurable log file, preventing logs from being lost if the console is closed.
JVM Management You can easily set JVM parameters (memory settings, classpath, system properties) directly in the Wrapper's configuration file, without modifying startup scripts.
Security The Wrapper can run your Java application as a specific, non-privileged user, which is a critical security best practice for services.

How it Works (The Architecture)

The architecture is quite simple:

Java Service Wrapper如何实现服务守护?-图2
(图片来源网络,侵删)
  1. Native Executable: The Wrapper (wrapper.exe on Windows, wrapper on Linux/macOS) is installed as a service by the system.
  2. Wrapper Configuration: You create a configuration file (e.g., wrapper.conf) that tells the Wrapper how to launch and manage your Java application.
  3. Your Java Application: Your Java application needs to be slightly modified to listen for events from the Wrapper, primarily the "stop" event. This is usually done by including the Wrapper's JAR file in your classpath and using its API.

Diagram:

+-----------------+      +-----------------------+      +-----------------------+
|   OS (Windows/  |      |  Native Wrapper       |      |   Your Java           |
|   Linux)        |----->|  (wrapper.exe/wrapper)|----->|   Application         |
| (Start/Stop)    |      |  (Service Daemon)     |      |   (Running in a JVM)  |
+-----------------+      +-----------------------+      +-----------------------+
       ^                                                      |
       | (Sends signals like "STOP")                          | (Listens for "STOP" signal)
       +------------------------------------------------------+

Getting Started: A Simple Example

Let's create a simple "Hello World" service.

Step 1: Download the Wrapper

Step 2: Prepare Your Java Application Your application needs to be able to respond to the stop command. The easiest way is to use the WrapperManager class.

Java Service Wrapper如何实现服务守护?-图3
(图片来源网络,侵删)
// HelloWorldService.java
import org.tanukisoftware.wrapper.WrapperManager;
import org.tanukisoftware.wrapper.WrapperListener;
public class HelloWorldService implements WrapperListener {
    public static void main(String[] args) {
        // Start the application through the Wrapper
        WrapperManager.start(new HelloWorldService(), args);
    }
    @Override
    public void controlEvent(int eventCode) {
        // This method is called when the Wrapper receives a control event (e.g., stop, restart)
        if (eventCode == WrapperListener.EVENT_FLAG_CONSOLE_STOP
                || eventCode == WrapperListener.EVENT_FLAG_SHUTDOWN) {
            System.out.println("Received stop/shutdown event. Shutting down gracefully...");
            // Add your clean-up logic here
        }
    }
    @Override
    public Integer start(String[] args) {
        // This is called when the service is started
        System.out.println("Hello World Service is starting!");
        while (true) {
            System.out.println("Service is running...");
            try {
                Thread.sleep(5000); // Run every 5 seconds
            } catch (InterruptedException e) {
                // This is how the service is typically stopped
                Thread.currentThread().interrupt();
                break;
            }
        }
        System.out.println("Hello World Service is stopping!");
        return null; // Return null on a normal shutdown
    }
}

Step 3: Compile and Package You need the wrapper.jar from the download in your classpath to compile.

# Create a lib directory
mkdir lib
# Copy wrapper.jar from the downloaded zip into the lib directory
# (Assuming the zip is extracted and wrapper.jar is in wrapper/lib/)
cp wrapper/lib/wrapper.jar lib/
# Compile your application
javac -cp ".:lib/wrapper.jar" HelloWorldService.java

Step 4: Create the Wrapper Configuration Create a file named wrapper.conf in the same directory.

# wrapper.conf
#----------------------------------------------------
# Wrapper Java Application
#----------------------------------------------------
wrapper.java.command=java
# Tell the Wrapper where to find your application's main class
wrapper.java.mainclass=HelloWorldService
# Classpath for your application and the wrapper library
wrapper.java.classpath=.:lib/wrapper.jar:.
# JVM arguments (e.g., memory settings)
wrapper.java.additional.1=-Xmx128m
#----------------------------------------------------
# Wrapper Application Properties
#----------------------------------------------------
# Name of the service
wrapper.name=HelloWorldService
# Display name in the service manager
wrapper.displayname=Hello World Service
# Description of the service
wrapper.description=A simple Hello World service.
#----------------------------------------------------
# Wrapper Logging
#----------------------------------------------------
# Log file to write output to
wrapper.logfile=logs/wrapper.log
# Log level (INFO, DEBUG, etc.)
wrapper.logfile.format=LPTM
wrapper.logfile.loglevel=INFO
#----------------------------------------------------
# Wrapper PID and Security
#----------------------------------------------------
# PID file
wrapper.pidfile=wrapper.pid
# Run as a specific user (optional, but recommended)
# wrapper.ntservice.account=YourServiceUser
# wrapper.ntservice.password=YourPassword

Step 5: Install and Run the Service Navigate to your project directory in the command prompt and use the wrapper executable.

# On Windows
wrapper.exe -i install
# On Linux
sudo ./wrapper install

Now you can control your service using the system's service manager:

  • Windows:
    • Open services.msc and find "HelloWorldService".
    • Or use the command line: net start HelloWorldService
  • Linux (with systemd):
    • sudo systemctl start HelloWorldService
    • sudo systemctl status HelloWorldService
    • sudo journalctl -u HelloWorldService to view logs.

The Generic Concept: Implementing a Service Without the Wrapper

Sometimes, you don't need the heavy lifting of the Tanuki Wrapper. You can create a service using OS-specific scripts or more modern Java frameworks.

A. Using OS-Level Scripts (Simple but Less Robust)

This approach involves creating a shell script (for Linux) or a batch file (for Windows) that launches your Java application with nohup (Linux) or using javaw.exe (Windows).

Linux (myapp.sh):

#!/bin/bash
# chkconfig: 345 99 10
# description: My Awesome Java App
# Path to your Java executable
JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
APP_HOME=/opt/myapp
APP_JAR=myapp.jar
PID_FILE=/var/run/myapp.pid
# Function to start the service
start() {
    if [ -f $PID_FILE ]; then
        echo "Service already running"
    else
        echo "Starting service..."
        nohup $JAVA_HOME/bin/java -jar $APP_HOME/$APP_JAR > /var/log/myapp.log 2>&1 &
        echo $! > $PID_FILE
    fi
}
# Function to stop the service
stop() {
    if [ -f $PID_FILE ]; then
        echo "Stopping service..."
        PID
分享:
扫描分享到社交APP
上一篇
下一篇