1. 程式人生 > >製作windows服務(java)

製作windows服務(java)

前言

在之前我寫了篇如何呼叫微信掃碼支付介面的部落格http://blog.csdn.net/qq_32574435/article/details/78952325,但是這個存在一個問題,就是在使用者支付成功之後系統如何通知使用者,說白了就是給使用者一個反饋。人家給了錢你不管是網頁自動跳轉,還是傳送支付成功的簡訊,總得通知人家,這樣起碼不會讓使用者擔心我們是不是沒收到錢,業務是否訂購成功。對於支付成功之後的通知使用者的方式,常見的就是當前網頁跳轉,不過我聽說這個對伺服器有一定的要求,然後我最終選擇了製作一個windows服務的形式,不斷去查詢資料庫,將滿足條件的使用者傳送簡訊,比如說有個標誌flag欄位,當值為0時,傳送簡訊,然後將值改為1。其實製作這個windows服務並不難,網上教程也很多,只不過我當時在這裡花了好長的時間,所以我得把這個過程記下來,紀念一下自己跳過的坑。

開發語言:java
開發工具:eclipse
資料庫:oralce
架構:spring + mybatis

實現過程

一、方案的選擇
以下是我當時考慮的兩種方案:

1、新建一個web專案,使用監聽器的方法,web.xml中註冊一個監聽器,然後利用專案的啟動呼叫監聽器的初始化方法,去啟動一個執行緒,這個執行緒的作用就是不斷去查詢資料庫,然後將滿足條件的使用者傳送成功簡訊。

2、新建一個普通的java maven專案,製作成windows服務,然後將專案製作成jar包,再將jar包製作成windows服務,隨著伺服器的啟動去呼叫main方法啟動執行緒,也是不斷去查詢資料庫,然後將滿足條件的使用者傳送成功簡訊。如果是部署到windows伺服器的話,可以寫成windows服務,如果是部署到linux伺服器的話,建議寫成一個定時任務。後面這個我沒做過,請大家自行去百度。

第一個方案是我百度了好久,是我想用的方案,因為這些組成因素對於我來說還是比較熟悉的。不過後來這個方案被否決了,主要是聽說當時web有個延遲的東西在裡面,當然我也不是很理解,老大推薦我做成一個windows服務的形式,因為他說這個方案比方案一較好,而且製作windows服務是java程式設計師的必修課,最終,我選擇了方案二。

二、開發流程

1、第一步當然是新建一個普通的java maven專案,注意不要是web專案。
2、架構的選擇,我這裡選擇的是spring + mybatis 。
3、首先是配置mybatis,然後寫curd的程式碼,這些都沒啥好說的。然後就到了spring操作mybatis這個了,以前我一般是使用springmvc mybatis spring 這三個架構組合,然後使用註解的形式,按照依賴關係,比如說@Controller @Resource(name = “UserService”) dao 的方式來實現service 呼叫dao 。但是現在這個不是web專案,這個方法在這裡不適用啊。然後我就想到了我之前測試mybatis的程式碼

public class TestMybatis {

    private ApplicationContext ctx = null;
    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void setUp() throws Exception {
        try {
            ctx = new ClassPathXmlApplicationContext("classpath:META-INF/spring/applicationContext.xml");
            sqlSessionFactory = (SqlSessionFactory)ctx.getBean("sqlSessionFactory");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    @Test
    public void testOneLevelCache() throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        String account = "1827758888";
        String password = "700cac7c";
        User user = userMapper.findByAccount(account, password);
        System.out.println(user);
        sqlSession.close();*87
    }   
    }

我之前都是通過這樣的單元測試來測試程式碼是否正常的,我將上面的程式碼簡單改寫之後(具體怎麼寫我也忘了),然後每次通過建立session會話的方式從而來實現對資料庫的操作,但是當時被否決了。我用這種方式打成jar包,然後進入cmd ,到達你放jar包的路徑,執行 java -jar xxx.jar 執行,發現是可以執行的,但是執行一段時間之後,就會報異常,好像是獲取session失敗還是獲取bean失敗(具體沒記錄下來),這麼說這種方式應該是行不通的。(感興趣的朋友可以探究下,然後給我留言分享)

後面我選用了下面獲取bean這樣的方式,一直執行,都未報錯。
這裡寫圖片描述

這裡寫圖片描述

使用getBean的方式避開了每次都要建立session,也避免了執行一段時間產生異常情況。

4、寫一個執行緒,使用死迴圈的方式,不斷的執行程式碼
5、啟動執行緒方式,main方法

public class SendMsgTask {

    public static void main(String[] args) {

        SendMsgThread  sendMsg = new SendMsgThread();
        sendMsg.start();
    }
}

6、接下來先將程式碼打成jar包,注意我這個是maven專案,大家可以參考下這個連結
http://blog.csdn.net/xiao__gui/article/details/47341385 寫的很好,我是在pom.xml配置檔案中配置,然後左鍵選中專案,然後右鍵 run as —— maven install ,如果專案正常的話,那麼就會在target資料夾下生成你所需要的jar包(其實就是一些class檔案)
這裡寫圖片描述

圖中箭頭的sendmsgtask.jar就是你需要的jar包,有興趣的朋友可以點開看看,裡面就是class檔案和maven的配置資訊,然後旁邊的sendmsgtask-sources.jar裡面放置的是原始檔java程式碼。
打成jar包的時候,建議大家複製出來,右鍵解壓,點開資料夾檢視檔案是否齊全,有時候打包的時候會少了conf這個包,解決方法:選中當前專案——project——clean 重新編譯專案在打包基本即可。

7、jar包測試
當你製作成jar的時候,個人建議是先用cmd執行這個jar包來檢視是否正常,如果有問題的話控制檯會列印輸出資訊,這樣就可以排除,避免製作成windows服務太難排查問題。
自己新建個資料夾,將上圖中的lib資料夾(執行需要的jar包)和sendmsgtask.jar放進去,也許你會問怎麼知道複製出來的時候,lib的相對於sendmsgtask.jar路徑,請看下面這個sendmsgtask.jar中maven的配置圖
這裡寫圖片描述
至於路徑可以參考下圖,我這裡涉及到日誌路徑,所以測試的朋友可以先向我這樣編寫路徑,到時候再將com/aotain/sendmsg/util/LogUtil.java輸出日誌路徑改為自己的路徑。
這裡寫圖片描述

然後進入cmd 輸入下圖的命令 f: cd 到 jar包所需要的路徑,然後執行java -jar sendmsgtask.jar ,如果一切正常的話,將會輸出下面的日誌資訊。恭喜你,已經完成一半了,接下來是製作成windows服務了。
這裡寫圖片描述

8、製作windows服務的工具選擇
其實吧,我試過很多個製作windows服務的工具,不過也就只有一個成功了。不知道是工具不能實現還是我的操作不對,我在這個流程上面花了好多時間,搞得我都快瘋了。
我一開始使用的是javaservice來製作,參考了下面的連結http://blog.csdn.net/sky1718/article/details/51103865但是不成功,好像提示啟動失敗。我當時也使用了一個另外一個工具prunsrv,有人介紹它是tomcat製作windows服務的,我當時想我終於要做出來了,心裡有那麼一點小竊喜。但是事與願違,啟動的時候報錯 :服務已經安裝,但是啟動失敗(英文大概意思),我當時還去查看了計算機的系統日誌,也沒給我多大線索,當時花了好多時間都做不出來,都開始懷疑人生了。
後來我使用了wrapper-windows-x86這個工具,在經過一段時間的搗鼓之後,終於成功了。

9、製作流程
其實這個教程網上有很多。下面有詳細的教程。
第一步當然是下載工具:到官網https://wrapper.tanukisoftware.com/doc/english/download.jsp下載windows x86的社群免費版本。這裡要說明下這個工具的分64位和32位,不過64位是收費版,他會先讓你使用一段時間,然後證書過期之後,就會程式停止,我記得當時好像是每十五分鐘服務會停止,然後讓你手動去開啟服務,這個在裡面的配置檔案也有說明。所以不管是64位還是32位的電腦,建議直接下載這個工具的32位的。
這裡寫圖片描述
當然大家要是有積分的話也可以到這裡下載http://download.csdn.net/download/love_smallbear/2166538,我用的就是這個。
其實準備好jar包和工具之後,只需要修改工具的配置檔案即可,這裡是製作的另外一個核心。我來詳解一下。
至於製作流程參考的這個連結http://blog.csdn.net/xs_00/article/details/50818362裡面寫的太麻煩,其實你主要是看配置檔案conf/wrapper.conf裡面的引數解析即可
這裡僅僅列出需要修改和需要注意的地方
8.1 找到wrapper.java.command=java
如果本機已配置了jre,那麼此項不需更改;否則的話,需要將jre複製到myWindowServ資料夾路徑下
(如和bin在 同一級,修改wrapper.java.command=../jre/bin/java.exe《注:這裡需要將編譯jar包jre安裝檔案全部拷貝過來。》)
8.2 指定wrapper的啟動方式,用wrapper代理啟動不容易出現問題,不然 老報test.Main不存在的異常。
wrapper.java.mainclass=org.tanukisoftware.wrapper.test.Main
修改成
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp
8.3 將程式執行需要的jar包都列出來 lib資料夾中的wrapper.jar是必需的
wrapper.java.classpath.1=../lib/wrapper.jar
wrapper.java.classpath.2=../application/myjar.jar
8.4 配置程式執行的所需要的記憶體大小
# Initial Java Heap Size (in MB)
#wrapper.java.initmemory=3
# Maximum Java Heap Size (in MB)
#wrapper.java.maxmemory=64
修改成
# Initial Java Heap Size (in MB)
wrapper.java.initmemory=128
# Maximum Java Heap Size (in MB)
wrapper.java.maxmemory=256
這裡是限制服務所佔用的最小和最大記憶體,根據程式執行的效果也可以不改。
8.5 指定程式的主類
如 com.weiguo.mypro.TimerRun 是 myJar打包工程中main方法所在的類,
就需要如下配置:
wrapper.app.parameter.1=com.weiguo.mypro.TimerRun
以下的一些設定 就是服務本身的屬性設定,可以 設定—控制面板–管理工具–服務–隨便選中一個服務–右鍵屬性看到。
8.6 控制檯執行時的名稱
wrapper.console.title=TestServer
8.7 指定服務的名稱
wrapper.ntservice.name=TestServer
8.8 windows服務的顯示名稱
wrapper.ntservice.displayname=TestServer
8.9 服務描述
wrapper.ntservice.description=TestServer描述
8.10 啟動模式,預設是自啟動AUTO_START or DEMAND_START
wrapper.ntservice.starttype=AUTO_START
9 執行InstallApp-NT.bat安裝服務,執行StartApp-NT.bat啟動服務。
10 可以暫停,重啟服務 停止服務 PauseApp-NT.bat ResumeApp-NT.bat StopApp-NT.bat
11 如果要解除安裝這個服務的話,執行UninstallApp-NT.bat解除安裝服務。

製作流程可以參考我的,簡單粗暴有效
第一步:在f盤新建一個資料夾,取個名字,比如:sandmsgTest,再將wrapper-windows-x86-32-3.2.3.zip解壓,將裡面的lib bin conf logs 這個四個資料夾複製到sandmsgTest裡面,在新增一個檔案叫做application ,將你做好的jar包 sendmsgtask.jar放進application 這裡,將你需要的jar包都放進lib資料夾,結果請看下圖
這裡寫圖片描述

這裡寫圖片描述
當然這裡jar包太多,我只截圖了其中一部分

第二步,修改配置檔案,重要
開啟wrapper.conf配置檔案,參考引數解釋來修改成自己的資訊
有兩個細節要注意:一個是你這次需要的jar包,最好自己一個個手寫進入,我試過用*表示,結果報錯,請看下圖
這裡寫圖片描述
第二個細節,就是你如果對其中的引數修改,要生效的話,記得去掉前面的 # 註釋符號,我當時就犯了修改沒去掉註釋符這個低階的錯誤,導致一直失敗。檢查沒問題之後進入下一步

第三步,執行
你開啟bin檔案,然後看到裡面的bat檔案,
這裡寫圖片描述
至於功能,百度下前面開頭的單詞即可,也可以自己改掉檔名字,不會影響功能,因為都是去讀取配置檔案來執行。
先執行安裝命令InstallTestWrapper-NT.bat,沒報錯的話繼續執行StartTestWrapper-NT.bat開啟服務命令,如果雙擊出現無許可權訪問,建議右鍵以管理員許可權執行即可。
如果一直都沒報錯,就可以點開我的電腦 ——右鍵管理——服務和應用程式——服務 來查詢你啟動的服務,如果一切正常,那麼將會出現下圖。
這裡寫圖片描述

那麼恭喜你,windows服務製作成,你可以定時檢視下服務執行日誌來看系統是否正常,如下圖

這裡寫圖片描述

結尾

其實這個並不難實現,百度上也有很多例子,不過有一些感覺是不靠譜的,這個是例子是我自己全程跑完正常的。所以在這裡給大家一個參考的方向,少走彎路。

下面是我的maven專案,匯入加上自己的配置即可,如果匯入報錯:Project build error: Non-resolvable parent POM: Failure to find
com.aotain:bms:pom:1.0.0 in http://repo.maven.apache.org/maven2 was
cached in the local repository, resolution will not be reattempted until the
update interval of central has elapsed or updates are forced and
‘parent.relativePath’ points at wrong local POM 這個其實我也不大懂怎麼解決,如果有時間的話新建一個專案,然後將對應檔案複製出來,或者有朋友成功解決了這個問題的麻煩給我留言,學習下。

原始碼下載地址:
http://download.csdn.net/download/qq_32574435/10188032