由於要做手機端安卓程序,所以使用java來開發。后來又看了javaweb,覺得java還是很不錯的,功能很強大,可以做很多事,最重要的是資源非常豐富,有很多開源的庫框架之類。
最近用java做一個服務器端程序,於是就記錄下吧。
實際上是一個控制台程序,功能並復雜,主要是開一個socket端口,然后有傳感器設備連接過來,連上以后就不停的接受和發送數據,收的數據以后做一下解析,再將數據保存到數據庫中。
由於要操作數據庫,所以就直接把web端用的東西直接拿過來,使用spring+hibernate,這樣就不用去搞數據庫鏈接之類的事情了,和web項目一樣,通過maven來引入需要的jar包,改一下web項目中使用的pom.xml把不需要的東西去掉。
可能是spring一般都在web項目中使用,在做控制台程序的時候,打包出來點問題,在調試的時候運行沒有問題,但打包以后,使用java -jar 的方式來運行就出錯了,主要是因為找不到schema,不過還好,經過一番搜索這個問題很快就解決了。
使用一個maven插件,打包的時候對依賴的schema文件進行處理就可以了。

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>2.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <finalName>----文件名稱-----</finalName> <shadedArtifactAttached>true</shadedArtifactAttached> <shadedClassifierName>jar-with-dependencies</shadedClassifierName> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.xxxx.xxxx</mainClass> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/spring.handlers</resource> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/spring.schemas</resource> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/spring.tooling</resource> </transformer> </transformers> </configuration> </execution> </executions> </plugin>
加入spring和hibernate之后,這個控制台就有了很好的操作數據庫的能力,可以使用orm這很方便的。另外也可以使用spring提供的定時器功能了,這個項目中是需要使用定時任務的。
服務器程序,日志是要有的,使用log4j就可以了,log4j在一般的web項目中都有,直接拿過來就可以。
這些東西都配置好以后,實際上工作就已經完成了三之一。
這里再說一下socket吧,在客戶連接過來的時候,有幾種不同的處理方式。
1.將所有的客戶端連接放到一個列表里,然后再開單獨的線程,對列表中的連接進行處理,比如遍歷客戶端的列表讀取發送過來的數據,這種方式有一個缺點,就是在讀取數據有時候如果客戶端網絡異常線程就會阻塞,雖然可以設置超時,但讀取的線程卡在那里影響其他的客戶端是不太好的。
2.有客戶端連過來的時候就開一個新的線程,這樣客戶端之間就不會互相影響了,但如果客戶端太多開太多的線程會占用較多的服務器端資源。
由於目前客戶端數量不多,所以采用第二種方式。
程序寫好以后,就放到公司的一台pc機上測試運行了,第二天早上看的時候發現晚上9點多就卡在那里不動了,一開始以為是socket的問題,改了以后放在那里繼續跑,第三天早上看還是卡在那里。然后寫了一些測試的代碼,發現是數據庫連接池的問題,由於開了很多線程,數據庫連接不夠用了所以就卡在那里,改了一下c3p0的連接池的設置就好了。
當然,如果並發連接數太多對數據庫的性能是有影響的,cpu頻率會升高。就目前的情況來看,客戶端數量不多是沒什么問題的,如果客戶端的數量實在太多,就需要采用其他的方式來處理,比如讓10個或者100個客戶端共用一個線程,將socket和數據庫操作放到不同的線程等等。當然這樣程序就會變得比較復雜,需要用更多的時間來做,如果是要快速交付,就需要采用“簡單粗暴”的方式。
一般的程序都下不會對性能有非常高的要求,以至於要用c或者c++去做開發,基於開發效率考慮使用java開發是很不錯的。