ฉันจะเรียกใช้ jar ปฏิบัติการสปริงบูตในสภาพแวดล้อมการผลิตได้อย่างไร


105

วิธีการปรับใช้ที่ต้องการของ Spring boot คือผ่านไฟล์ jar ที่ปฏิบัติการได้ซึ่งมี tomcat อยู่ภายใน

java -jar myapp.jarมันเป็นที่เริ่มต้นด้วยการที่เรียบง่าย

ตอนนี้ฉันต้องการปรับใช้ jar นั้นกับเซิร์ฟเวอร์ linux ของฉันบน EC2 ฉันขาดอะไรไปหรือฉันจำเป็นต้องสร้างสคริปต์ init เพื่อเริ่มต้นแอปพลิเคชันเป็น daemon อย่างถูกต้องหรือไม่

ถ้าฉันเรียกjava -jarว่าแอปพลิเคชันตายเมื่อฉันออกจากระบบ

ฉันสามารถเริ่มได้ในหน้าจอหรือโนฮัป แต่มันไม่สวยหรูมากนักและการรีสตาร์ทในเซิร์ฟเวอร์ของฉันจะบังคับให้ฉันเข้าสู่ระบบและเริ่มกระบวนการด้วยตนเอง

แล้วมีบางอย่างสำหรับงานในสปริงบูตหรือไม่?


1
nohup / screen (วิธีการสกปรก), init / systemd / upstart (วิธีการที่เหมาะสม)

@RC ใช่มากที่ฉันรู้เช่นที่ฉันพูดถึง / sbin / init ด้วยสคริปต์ที่กำหนดเองใน /etc/init.d จะทำงานได้ แต่เป็นความคิดที่ว่าทุกคนควรสร้างสคริปต์ของตัวเองเพื่อจัดการ daemon (เริ่มหยุดรีสตาร์ทสถานะ)? รู้สึกเหมือนมีบางอย่างขาดหายไปในโซลูชันนั้น
Cleber Goncalves

ฉันรู้สึกว่ามีบางอย่างขาดหายไปในฤดูใบไม้ผลิบูต (เป็นโครงการที่ "สดใหม่" จริงๆ) เพียงแค่ติดต่อทีมที่รับผิดชอบและจัดทำข้อเสนอวิวัฒนาการ

ถ้าคุณสร้างคลังเก็บสงครามคุณสามารถใช้เวอร์ชันการแจกจ่ายของคุณบน Tomcat ซึ่งจะมีสคริปต์เริ่มต้นพร้อมใช้งาน ในทางกลับกันถ้าคุณใช้วิธีการทำงานของ jar คุณต้องสร้างสคริปต์เริ่มต้นที่กำหนดเอง ไม่แน่ใจว่ามันอยู่ในขอบเขตของรองเท้าบู๊ตหรือเปล่า แต่มันหายไปอย่างชัดเจนซึ่งมันแปลกมากดังนั้นฉันจึงถามในกรณีที่ฉันมองข้ามบางสิ่งไป จะ ping พวกเขา
Cleber Goncalves

คำตอบ:


96

โปรดทราบว่าตั้งแต่ Spring Boot 1.3.0.M1 คุณสามารถสร้างไหที่ปฏิบัติการได้อย่างสมบูรณ์โดยใช้ Maven และ Gradle

สำหรับ Maven เพียงใส่สิ่งต่อไปนี้ในpom.xml:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <executable>true</executable>
    </configuration>
</plugin>

สำหรับ Gradle ให้เพิ่มข้อมูลโค้ดต่อไปนี้ลงในbuild.gradle:

springBoot {
    executable = true
}

jar ที่เรียกใช้งานได้อย่างสมบูรณ์มีสคริปต์พิเศษที่ด้านหน้าของไฟล์ซึ่งช่วยให้คุณสามารถเชื่อมโยง jar Spring Boot ของคุณกับinit.dหรือใช้systemdสคริปต์ได้

init.d ตัวอย่าง:

$ln -s /var/yourapp/yourapp.jar /etc/init.d/yourapp

สิ่งนี้ช่วยให้คุณเริ่มหยุดและรีสตาร์ทแอปพลิเคชันของคุณเช่น:

$/etc/init.d/yourapp start|stop|restart

หรือใช้systemdสคริปต์:

[Unit]
Description=yourapp
After=syslog.target

[Service]
ExecStart=/var/yourapp/yourapp.jar
User=yourapp
WorkingDirectory=/var/yourapp
SuccessExitStatus=143

[Install]
WantedBy=multi-user.target

ข้อมูลเพิ่มเติมที่ลิงค์ต่อไปนี้:


4
คุณอาจต้องทำ$ chmod +x /etc/init.d/yourappเพื่อให้สามารถเริ่ม / หยุด / รีสตาร์ทได้
Rohith Nandakumar

คุณต้องให้สิทธิ์ผู้ใช้บริการของคุณในการอ่านและเรียกใช้ไฟล์ jar เสมอ คุณยังต้องกำหนดค่า Java เริ่มต้นสำหรับเซิร์ฟเวอร์และตัวแปรสภาพแวดล้อม Java เพื่อให้สิ่งต่างๆทำงานได้
micaro

ไม่ได้ผล! ฉันได้ลองแล้วและได้รับข้อผิดพลาดต่อไปนี้: ล้มเหลวในการเริ่ม MyApp.service: ไม่พบหน่วย MyApp.service
Martijn Hiemstra

9

วิธีที่ง่ายที่สุดและน่าเชื่อถือที่สุดในการเรียกใช้แอปพลิเคชัน Spring Boot ในการผลิตคือการใช้ Docker ใช้ Docker Compose, Docker Swarm หรือ Kubernetes หากคุณต้องการใช้บริการที่เชื่อมต่อหลายบริการ

นี่เป็นคำแนะนำง่ายๆDockerfileจากคู่มือSpring Boot Dockerอย่างเป็นทางการเพื่อให้คุณเริ่มต้น:

FROM frolvlad/alpine-oraclejdk8:slim
VOLUME /tmp
ADD YOUR-APP-NAME.jar app.jar
RUN sh -c 'touch /app.jar'
ENV JAVA_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]

นี่คือบรรทัดคำสั่งตัวอย่างเพื่อรันคอนเทนเนอร์เป็น daemon:

docker run \
  -d --restart=always \
  -e "SPRING_PROFILES_ACTIVE=prod" \
  -p 8080:8080 \
  prefix/imagename

3

แอปพลิเคชัน Spring boot ของฉันมีตัวเริ่มต้นสองตัว หนึ่งสำหรับการพัฒนาและอื่นสำหรับการผลิต สำหรับการพัฒนาฉันใช้วิธีการหลักดังนี้:

@SpringBootApplication
public class MyAppInitializer {

    public static void main(String[] args) {
        SpringApplication.run(MyAppInitializer .class, args);
    }

}

ตัวเริ่มต้นของฉันสำหรับสภาพแวดล้อมการผลิตขยายSpringBootServletInitializerและมีลักษณะดังนี้:

@SpringBootApplication
public class MyAppInitializerServlet extends SpringBootServletInitializer{
    private static final Logger log = Logger
            .getLogger(SpringBootServletInitializer.class);
    @Override
    protected SpringApplicationBuilder configure(
            SpringApplicationBuilder builder) {
        log.trace("Initializing the application");
        return builder.sources(MyAppInitializerServlet .class);
    }

}

ฉันใช้ gradle และไฟล์ build.gradle ของฉันใช้ปลั๊กอิน ' WAR ' เมื่อฉันรันในสภาพแวดล้อมการพัฒนาฉันใช้งานbootrun เมื่อฉันต้องการปรับใช้กับการใช้งานจริงฉันใช้งานแอสเซมบลีเพื่อสร้าง WAR และปรับใช้

ฉันสามารถใช้งานได้เหมือนแอปพลิเคชั่นสปริงทั่วไปในการผลิตโดยไม่ลดข้อได้เปรียบที่ได้รับจากแมวตัวผู้ในตัวในขณะที่พัฒนา หวังว่านี่จะช่วยได้


2

ในสภาพแวดล้อมการใช้งานจริงคุณต้องการให้แอปของคุณเริ่มทำงานอีกครั้งในการรีสตาร์ทเครื่อง ฯลฯ การสร้างสคริปต์ /etc/init.d/ และลิงก์ไปยังระดับรันเลเวลที่เหมาะสมเพื่อเริ่มต้นและหยุดเป็นแนวทางที่ถูกต้อง Spring Boot จะไม่ครอบคลุมถึงสิ่งนี้เนื่องจากเป็นการตั้งค่าเฉพาะระบบปฏิบัติการและมีตัวเลือกอื่น ๆ อีกมากมายคุณต้องการให้ทำงานในคุก chroot หรือไม่จำเป็นต้องหยุด / เริ่มก่อนซอฟต์แวร์อื่น ๆ


2

คุณสามารถใช้โปรแกรมที่เรียกว่าหัวหน้างาน ในการกำหนดค่าหัวหน้างานคุณสามารถกำหนดบริการต่างๆและวิธีดำเนินการเหมือนกันได้

สำหรับ Java java -jar springbootapp.jarและฤดูใบไม้ผลิการใช้งานคำสั่งบูตจะเป็น

สามารถให้ตัวเลือกเพื่อให้แอปพลิเคชันทำงานอยู่เสมอดังนั้นหาก EC2 รีสตาร์ท Supervisor จะรีสตาร์ทแอปพลิเคชันของคุณ

ฉันพบว่า Supervisor ใช้งานง่ายเมื่อเทียบกับการใส่สคริปต์เริ่มต้นใน /etc/init.d/ สคริปต์เริ่มต้นจะหยุดทำงานหรือเข้าสู่สถานะรอในกรณีที่เกิดข้อผิดพลาด


2

หากคุณใช้ gradle คุณสามารถเพิ่มสิ่งนี้ลงใน build.gradle ของคุณได้

springBoot {
    executable = true
}

จากนั้นคุณสามารถเรียกใช้แอปพลิเคชันของคุณโดยพิมพ์. /your-app.jar

นอกจากนี้คุณสามารถดูคำแนะนำฉบับสมบูรณ์ได้ที่นี่เพื่อตั้งค่าแอปของคุณเป็นบริการ

56.1.1 การติดตั้งเป็นบริการ init.d (ระบบ V)

http://docs.spring.io/spring-boot/docs/current/reference/html/deployment-install.html

ไชโย


จริงๆแล้วมันควรจะเป็นbootRepackage { executable = true }ดูdocs.spring.io/spring-boot/docs/current/reference/html/…
Philippe

2

บน Windows OS ที่ไม่มีบริการ

start.bat

@ECHO OFF
call run.bat start

stop.bat:

@ECHO OFF
call run.bat stop

run.bat

@ECHO OFF
IF "%1"=="start" (
    ECHO start myapp
    start "myapp" java -jar -Dspring.profiles.active=staging myapp.jar
) ELSE IF "%1"=="stop" (
    ECHO stop myapp
    TASKKILL /FI "WINDOWTITLE eq myapp"
) ELSE (
    ECHO please, use "run.bat start" or "run.bat stop"
)
pause

1

ฉันเริ่มแอปพลิเคชันที่ฉันต้องการเรียกใช้อย่างต่อเนื่องหรืออย่างน้อยกึ่งถาวรผ่านหน้าจอ -dmS NAME / path / to / script เท่าที่ฉันได้รับแจ้งนี่เป็นวิธีที่ดีที่สุด


0

นี่เป็นวิธีง่ายๆคุณสามารถใช้ปลั๊กอิน spring boot maven เพื่อเสร็จสิ้นการปรับใช้โค้ดของคุณ

การกำหนดค่าปลั๊กอินเช่น:

<plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <jvmArguments>-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=${debug.port}
                    </jvmArguments>
                    <profiles>
                        <profile>test</profile>
                    </profiles>
                    <executable>true</executable>
                </configuration>
            </plugin>

และjvmArtumentsเพิ่มสำหรับคุณ jvm profilesจะเลือกโปรไฟล์เพื่อเริ่มแอปของคุณ executableสามารถทำให้แอปของคุณทำงานได้อย่างไม่น่าเชื่อ

และถ้าคุณเพิ่มmvnwในโครงการของคุณหรือคุณมี maven enveriment คุณสามารถเรียก./mvnw spring-boot:runหา mvnw หรือmvn spring-boot:runmaven

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.