You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在AWS EC2上无需外部调用永久运行Firebase监听Jar文件?

Firebase Java Service Optimization & EC2 Permanent Run Guide

Hey there! Let's tackle your two main questions: optimizing your Firebase listener code, and getting your JAR to run non-stop on AWS EC2. I'll break this down clearly for you as a Java beginner.

Part 1: Optimizing Your Firebase Listener Code

First, let's fix some issues in your current code—right now it has a couple of problems that could cause unexpected behavior or resource waste:

Key Issues in Your Current Code

  • Repeated Listener Registration: Your while(true) loop keeps adding new ValueEventListener instances every time it runs. This means every data change will trigger all registered listeners (not just one), leading to duplicate database updates and wasted memory.
  • Useless Loop + Latch Block: The latch.await() call blocks the main thread forever on the first run, so the loop never executes a second time anyway. You don't need the loop at all because Firebase listeners stay active as long as your app is running.

Optimized Code Example

import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.ValueEventListener;
import com.google.firebase.database.DatabaseError;
import java.util.concurrent.CountDownLatch;

public class FirebaseSyncService {
    // Mark as volatile to ensure thread-safe access across listener and main thread
    private static volatile DataSnapshot nextGames;

    public static void main(String[] args) {
        CountDownLatch latch = new CountDownLatch(1);
        
        // Initialize your Firebase reference once
        DatabaseReference nextGamesRef = FirebaseDatabase.getInstance().getReference("your-next-games-path");

        // Register the listener ONCE—Firebase will keep listening for changes indefinitely
        nextGamesRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot snapshot) {
                nextGames = snapshot;
                // Ensure setNextGame handles database updates safely (use thread-safe logic if needed)
                setNextGame(nextGames);
                System.out.println("Successfully synced latest game data");
            }

            @Override
            public void onCancelled(DatabaseError error) {
                // Use System.err for error messages to distinguish them from regular logs
                System.err.println("Firebase listener cancelled with error: " + error.getMessage());
                System.err.println("Error details: " + error.getDetails());
                // Uncomment below if you want to shut down the service on critical errors
                // latch.countDown();
            }
        });

        try {
            // Block the main thread to keep the service running
            latch.await();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            System.err.println("Service was interrupted: " + e.getMessage());
        }
    }

    private static void setNextGame(DataSnapshot nextGames) {
        // Your database sync logic here
        // Tip: If writing to a SQL database, use connection pools and ensure thread safety
    }
}

What Changed & Why

  • Single Listener Registration: We moved the listener outside the loop so it only registers once. Firebase maintains this listener as long as your app is alive.
  • Cleaner Latch Usage: The latch only exists to keep the main thread from exiting (since Java apps shut down when the main thread finishes). We added proper interrupt handling for graceful service stops.
  • Better Error Logging: Using System.err for errors makes them easier to spot in logs, and we included more details for debugging.

Part 2: Running Your JAR Permanently on AWS EC2

You're right—Tomcat is for web apps that respond to HTTP requests, so it's not a good fit for your background service. Instead, use systemd (a built-in Linux service manager) to make your JAR run automatically on boot, restart if it crashes, and stay running indefinitely.

Step-by-Step Setup

  1. Move Your JAR to a Stable Directory
    SSH into your EC2 instance and copy your JAR to a dedicated folder (e.g., /opt/firebase-sync/):

    sudo mkdir -p /opt/firebase-sync
    sudo cp /path/to/your/firebase-sync-service.jar /opt/firebase-sync/
    sudo chown ec2-user:ec2-user /opt/firebase-sync/* # Replace ec2-user with your instance's username (e.g., ubuntu for Ubuntu instances)
    
  2. Create a Systemd Service File
    Create a file at /etc/systemd/system/firebase-sync.service with the following content (use sudo nano /etc/systemd/system/firebase-sync.service to edit):

    [Unit]
    Description=Firebase to Database Sync Service
    After=network.target # Wait for network to be ready before starting
    
    [Service]
    User=ec2-user # Match your instance's username
    WorkingDirectory=/opt/firebase-sync
    ExecStart=/usr/bin/java -jar firebase-sync-service.jar
    Restart=always # Automatically restart if the service crashes
    RestartSec=5 # Wait 5 seconds before restarting
    StandardOutput=journal+console # Send logs to systemd's journal
    StandardError=journal+console # Send errors to the same journal
    
    [Install]
    WantedBy=multi-user.target # Start when the system reaches multi-user mode
    
  3. Enable & Start the Service
    Run these commands to activate the service:

    sudo systemctl daemon-reload # Reload systemd to recognize the new service
    sudo systemctl start firebase-sync # Start the service now
    sudo systemctl enable firebase-sync # Set it to start on boot
    
  4. Check Service Status & Logs

    • To see if the service is running: sudo systemctl status firebase-sync
    • To view real-time logs: journalctl -u firebase-sync -f (press Ctrl+C to exit)
    • To view all logs for the service: journalctl -u firebase-sync

Alternative: Temporary Run with nohup

If you need a quick temporary fix (not recommended for production), use nohup to run the JAR in the background even after you close your SSH session:

nohup java -jar firebase-sync-service.jar > service.log 2>&1 &

This will write logs to service.log, but the service won't restart on crash or server reboot—so stick with systemd for production use.


内容的提问来源于stack exchange,提问作者waleed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 03:55:04