由于 springboot 是一個微服務框架,其生產部署的方式也需要盡可能的簡單,與常規的 web 應用有著一個巨大的不同之處,它可以內嵌一個 web 容器,如:tomcat、jetty等,不再需要將應用打包成容器規定的特定形式。
對于 springboot 來說,打包成一個簡單的 jar 包直接使用 java -jar即可啟動,這是一種非常優雅的方式,但同時也帶來了一定的問題,如:應用如何停止?在過去,應用程序是部署在特定的容器中的,使用容器提供的腳本可以優雅停服,但現在容器被內嵌了,腳本沒有了,怎么辦?直接 kill 是一種方式,但未免顯得太過粗魯,而且可能帶來許多意想不到的問題。
既然我們能想到問題,框架的制定者也會想到,那么他們有沒有為我們準備好解決方案呢?答案是有的,下面我介紹下我了解到的幾種方案。
1. 使用 endpoints
在 springboot 官方文檔的第4部分中介紹了為應用發布生產準備的各種特性,其中,通過 actuator 的 http endpoint,開發人員可以方便地對應用的監控與管理。
引入指定的 starter 包:
1
|
"org.springframework.boot:spring-boot-starter-actuator:${springbootversion}" |
在 application.yml 中打開如下兩個配置,即可實現通過 http 請求停止應用
1
2
3
4
5
6
|
management: security: enabled: false endpoints: shutdown: enabled: true |
操作命令如下:
1
|
curl -x post http: //host:port/shutdown |
但這種方式有一個非常嚴重的問題,那就是任意人都可以控制應用的停止,這對于一個生產應用無疑是不可接受的。有些人可能會想,現在的鏈接地址太簡單了,非維護人員也可以輕易地猜出來,如果使用一個非常復雜的地址是否可以避免這個問題。很好,這個提議不錯,那我們再看看 springboot 為我們提供的相關配置。
1
2
3
4
|
endpoints: shutdown: enabled: true path: /xxx |
配置完成后,上面的命令就不可用了,需更新命令為:
1
|
curl -x post http: //host:port/xxx |
其中的/xxx當然只是我隨手設置的一個,你可以設置任意的地址。雖然安全性高了那么一點,但這樣的安全級別仍然是無法應用到生產環境的。那是否還有其它的防護手段呢?有,除了修改shutdown的路徑外,我們還可以給所有的管理操作加上一個統一的上下文,配置獨立的端口,并限制指定ip訪問(一般限定為本機),配置如下:
1
2
3
4
5
6
|
management: security: enabled: false port: 9001 address: 127.0 . 0.1 context-path: /admin |
變更后的停服命令為:
1
|
curl -x post http: //127.0.0.1:9001/admin/xxx |
這樣其實已經足夠安全了,為了進一步的保證系統的安全,再給其加上一層 http basic auth。
增加 security 依賴:
1
|
"org.springframework.boot:spring-boot-starter-security:${springbootversion}" |
修改配置文件如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
endpoints: shutdown: enabled: true path: /xxx management: security: enabled: true port: 9001 address: 127.0 . 0.1 context-path: /admin security: basic: enabled: true path: /admin user: name: root password: 123456 |
配置完成后,最終的停服命令為:
1
|
curl -x post -u root: 123456 http: //127.0.0.1:9001/admin/xxx |
2. 注冊為系統服務
除了使用 java -jar 運行 springboot 應用程序外,還可以輕松地用 init.d 或 systemd 注冊成 linux/unix 系統服務,這使得在生產環境中,安裝和管理 springboot 應用程序變得非常簡單。
在maven工程里面,為了創建一個“完全可執行”的 jar,需要引入如下插件:
1
2
3
4
5
6
7
8
|
<plugin> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-maven-plugin</artifactid> <version> 1.5 . 2 .release</version> <configuration> <executable> true </executable> </configuration> </plugin> |
在 gradle 工程里面,等效配置如下:
1
2
3
4
5
6
7
|
plugins { id 'org.springframework.boot' version '1.5.2.release' } springboot { executable = true } |
配置完成后,即可以通過 ./application-name.jar 運行構建好的應用程序。
最后,我們需要將打包好的應用程序安裝成一個init.d 服務,這樣就可以很方便地使用 unix/linux 進行管理了。操作方式很簡單,只需要將應用程序簡單的鏈接到 init.d 即可(其中funda為我自己的應用名,自己實驗時需要視情況替換)。
1
|
ln -s /app/funda/funda.jar /etc/init.d/funda |
檢查鏈接是否建立成功
1
|
ls -l /etc/init.d/funda |
啟動服務,應用日志可查看文件 /var/log/funda.log
1
|
service funda start |
其它常用命令
1
2
3
4
|
# 查看應用運行狀態 service funda status # 停止應用 service funda stop |
問題匯總:
在鏈接成功后,應用啟動時,無法成功啟動,提示unable to find java,使用如下命令將jdk的java命令鏈接到/sbin/java即可。
1
|
ln -s /usr/local/jdk1. 8 .0_131/bin/java /sbin/java |
參考鏈接:
endpoints
monitoring and management over http
unix/linux services
unable to find java #5690
項目鏈接:
github : https://github.com/qchery/funda
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:https://blog.csdn.net/chinrui/article/details/78685032