將處理業務的流程拆分成一個一個鏈,前面處理完,再派給下一個,類似HTTP中的FILTER
不用安裝服務器,內嵌在SPRING容器中,對外支持多種格式的數據,外部系統如要和SPRING INTERGRATION整合,不需要再進行開發
處理流程一般就是,ADAPTER去讀取外部數據,轉換后放到CHANNEL中,ENDPOINT處理CHANNEL中的數據,委派給下一個CHANNEL,下一個ENDPOINT處理,通過ADAPTER寫到外部接口中。
- ADAPTER
外部系統與CHANNEL之間的橋梁,獲取外部數據將其放到CHANNEL去,有FTP,JMS,文件系統的
CHANNEL
里面放MESSAGE對象,MESSAGE里面可以放自定義對象,以提供消費者使用
ENDPOINT
CHANNEL的消費者,CHANNEL與ENDPOINT是一對一的關系,所以如果想在一個CHANNE下對應多個ENDPOINT,是做不到的,只能增加CHANNEL
Service Activators:從INPUT CHANNEL中取出一個對象作為參數,調用設置的POJO的方法,將結果放到OUTPUT CHANNEL中
Transformers:對CHANNEL中的對象進行類型轉換
決定流向的ENDPOINT:Routers,SPLITER
- 例子
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/integration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:stream="http://www.springframework.org/schema/integration/stream"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/stream
http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd">
<gateway id="cafe" service-interface="org.springframework.integration.samples.cafe.Cafe"/>
<channel id="orders"/>
<!-- 此處orders里面的對象是一個一個Message,調用payload則取到Order
調用items則得到OrderItem List,拆分成OrderItem以一個為單位放到
drinks中
-->
<splitter input-channel="orders" expression="payload.items" output-channel="drinks"/>
<channel id="drinks"/>
<!-- 此處drinks里面的對象是一個一個OrderItem,調用iced則取到布爾值
如果是true則放到coldDrinks中,如是false則放到hotDrinks中
-->
<router input-channel="drinks" expression="payload.iced ? 'coldDrinks' : 'hotDrinks'"/>
<channel id="coldDrinks">
<queue capacity="10"/>
</channel>
<service-activator input-channel="coldDrinks" ref="barista" method="prepareColdDrink" output-channel="preparedDrinks"/>
<channel id="hotDrinks">
<queue capacity="10"/>
</channel>
<!-- 將輸入通道中的OrderItem轉成Drink -->
<service-activator input-channel="hotDrinks" ref="barista" method="prepareHotDrink" output-channel="preparedDrinks"/>
<channel id="preparedDrinks"/>
<!-- 將通道中的Drink按一個Order進行合并成一個List<Order>-->
<aggregator input-channel="preparedDrinks" method="prepareDelivery" output-channel="deliveries">
<beans:bean class="org.springframework.integration.samples.cafe.xml.Waiter"/>
</aggregator>
<stream:stdout-channel-adapter id="deliveries"/>
<beans:bean id="barista" class="org.springframework.integration.samples.cafe.xml.Barista"/>
<poller id="poller" default="true" fixed-delay="1000"/>
</beans:beans>
Hibernate Tools是由JBoss推出的一個Eclipse綜合開發工具插件,該插件可以簡化ORM框架Hibernate,以及JBoss Seam,EJB3等的開發工作。Hibernate Tools可以以Ant Task以及Eclipse插件的形式運行。
Hibernate Tools Eclipse插件的特征
Hibernate Tools Eclipse插件具有以下特征或功能:
Mapping Editor(映射文件編輯器):該編輯器可以用來編輯Hibernate XML映射文件,提供代碼自動補全,語法高亮功能。
- 類名的自動補全
- 屬性/表的列名自動補全
Hibernate Console(Hibernate控制臺):它提供一個全新的Eclipse Perspective窗口,可以執行HQL,并查看查詢的結果。這是一個非常便利的工具,可以用來驗證HQL的語法是否正確。
Configuration Wizards and Code generation(Hibernate配置文件hibernate.cfg.xml創建導航,以及代碼生成器):支 持完全反向生成功能,可以從已有的數據庫生成Hibernate配置文件hibernate.cfg.xml,同時支持"click-and- generate"方式生成Java代碼(Hibernate POJOs),DAO,XML映射文件(.hbm.xml),以及schema 文檔(.hml)等文件。
Eclipse JDT integration(代碼補全):該工具支持Java代碼中的HQL輸入補全,以及對Java代碼中的HQL語法加以合法性驗證。
Hibernate Tools的使用
- Hibernate的配置文件hibernate.cfg.xml的生成 步驟:
1)Eclipse的菜單:選擇[File] -> [New] -> [Other] -> [Hibernate/Hibernate Configuration file (cfg.xml) ],“Next”按鈕
2)輸入 [Database dialect] ,[Driver Class],[Connection URL],以及[DB用戶名],[密碼]等
3)按下[Finish]按鈕,則自動生成hibernate.cfg.xml文件。
** "Create Console Configuration" checkbox默認為選擇狀態。被選擇的情況下,則進入“Hibernate Console Configuration ”(Hibernate Console)設置/創建頁面。
- 設置Hibernate Console Hibernate Tools支持創建多個Hibernate Console。
1)Eclipse菜單:選擇[File] -> [New] -> [Other] -> [Hibernate/Hibernate Console Configuration],“Next”按鈕
2)在所顯示的畫面上輸入Hibernate Console的名稱[Name],目標項目名[Project],Hibernate配置文件(hibernate.cfg.xml)的路徑[Configuration file]
3)按[Finish]按鈕,則創建Hibernate Console,同時顯示在"Hibernate Configurations"視圖中。
- Reverse engineering and code generation:利用"click-and-generate" Reverse Engineering以及代碼生成功能自動生成所需代碼。
※使用Hibernate code generation(Hibernate代碼生成器)之前,需要先配置/創建Hibernate Console。
1)可以從Hibernate 的Tool Bar,或"Run/Hibernate Code Generation"菜單啟動Hibernate代碼生成器。
2)在所顯示的畫面上,輸入 創建好的Hibernate控制臺名稱[Console Configuration],輸出路徑「Output directory」等信息。
** 其它可以實際情況加以設置。
3)打開Explore標簽,設置需要生成的代碼類型(Domain code, DAO等)
4)設置完成之后,按下[Run]按鈕
根據不同的配置,將自動生成Hibernate關聯文件,EJB3,JBoss Seam等文件。
Hibernate Tools其它參考資料
Hibernate Tools Reference Guide [官方文檔]
Hibernate Tools Eclipse Plugins [官方文檔,Hibernate Tools Eclipse插件]
完善api-doc,用eclipse生成javadoc的時候發生“編碼 GBK 的不可映射字符 ”,很是惱火。其實是字符編碼問題。
打開eclipse,project -> Generate javadoc 一項一項的選你要輸出javadoc的項目,在VM設置中加入以下代碼 -encoding utf-8 -charset utf-8
這次操作,輸出的html代碼不會發生“編碼 GBK 的不可映射字符 ”問題,而且html字符編碼都設為了UTF-8,問題徹底解決。
對應的ant target 如下
<target name="javadoc">
<echo>+---------------------------------------------------+</echo>
<echo>| Building Doc File |</echo>
<echo>+---------------------------------------------------+</echo>
<javadoc access="protected"
additionalparam="-encoding utf-8 -charset utf-8 "
author="true"
classpath="${classes.dir}"
destdir="${doc.dir}/api"
nodeprecated="false"
nodeprecatedlist="false"
noindex="false"
nonavbar="false"
notree="false"
packagenames="org.xxx.common.web.tag.go"
source="1.6"
sourcepath="${src.dir}"
splitindex="true"
use="true"
version="true"
>
<link href="http://java.sun.com/javase/6/docs/api/" />
</javadoc>
</target>
WEB程序調優
1.純JSP比JSF性能要好
2.樹形數據的顯示如果用JSF性能要差,不如用低層次的JAVASCRIPT
WEB SERVICE調優
1.性能不太好,尤其依賴于傳輸的SOAP大小,因為在XML與JAVA OBJECT的轉換中消耗太多
2.加緩存在SOAP上
3.JBOSS的WEB SERVICE有三個實現,原生的、CXF和METRO,性能最好的是METRO,最差是原生的
JBOSS中的TOMCAT調優
1.CONNECTOR參數
當進入JBOSS的請求到達maxThreads,且又高于acceptCount的時候,用戶就會收到Connection refused的錯誤信息,當HTTP請求的線程空閑了maxIdleTime時,系統就會殺掉這些線程,直到到達minSpareThreads數為止
2.如何計算程序就需的線程數
CPU數*200,如4核的設800
可以通過域名為jboss.web,name=http-127.0.0.1-8080,type=ThreadPool的MBEAN觀察實際的線程數
3.處理周期長的WEB線程
WEB線程處理請求時,并不會馬上結束,還會繼續傳遞到EJB層,這樣如果EJB層處理周期長,會導致WEB層請求數增長來處理新進來的請求
4.如何增大線程最大處理數
這完全依賴于CPU、RAM和SOCKET數
5.使用APACHE PORTABLE RUNTIME
增加APR包能提高性能20%,如果是WINDOWS系統則不建議
6.整合APACHE WEBSERVER與JBOSS SERVER
使用APACHE WEBSERVER作為JBOSS的前端,以達到HA的效果,又能提高20%的性能
結合方式是使用mod_jk mod_proxy_ajp mod_proxy_http
7.三種方式的比較
mod_proxy_ajp要高于其他兩種
8.引入mod_cluster
9.web.xml中關于JSP的調優
development=false,避免訪問前的檢查
checkInterval=0,避免JSP需要重新編譯
trimSpaces=true,刪除JSP中的空格
genStringAsCharArray=true
JBOSS中SERVICE的調優
SESSION BEAN
1.stateless session bean在池中數量大小的配置
每建一個SESSION BEAN,就會在jboss.j2ee域下建一個MBEAN,通過查看其信息得知BEAN的處理統計時間來調整BEAN數量大小,配置文件:/deploy/ejb3-interceptors-aop.xml
2.stateful session bean
SFSB是被JBOSS緩存在容器中,因此客戶端的每個請求都會立即響應,同樣也是通過SLSB的方式查看并調整CACHE的數量大小
3.SFSB與 SLSB的比較
SFSB性能要差10%
4.事務
EJB與普通RMI SERVICE相比,就是有完整的事務支持,如果EJB采用CMT,則可以保證其方法是在全局的事務上下文中被執行的,但開啟事務的成本太高,如果不需用到事務的方法需將事務關閉
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)5.自定義EJB容器
JBOSS是以攔截器的方式運行EJB的,如果EJB中不需要事務的支持,可將這個INTERCEPTOR注釋掉
<interceptor-ref name="org.jboss.aspects.
tx.TxPropagationInterceptor"/>6.比較軟的方式自定義EJB容器
將定義寫在新的XML文件中,以覆蓋原先的設定
<?xml version="1.0" encoding="UTF-8"?>
<aop xmlns="urn:jboss:aop-beans:1.0">
<domain name="Non Tx Stateless Bean" extends="Intercepted Bean"
inheritBindings="false">
<bind pointcut="execution(public * *->*(..))">
<interceptor-ref name="org.jboss.ejb3.stateless.
StatelessInstanceInterceptor"/>
<interceptor-ref name="org.jboss.ejb3.
AllowedOperationsInterceptor"/>
<stack-ref name="EJBInterceptors"/>
</bind>
</domain>
</aop>JMS
1.基本概念
JMS provider:JMS系統
Messages:客戶端交流的載體
Connection factories:產生鏈接的工廠
Destinations:有Queues和Topics
Queues:含有一堆Messag的隊列,只能發給一個客戶端
Topics:可以發給多個客戶端
JMS clients:生產和消費Message的東西
MDB:一個特殊的consumer
2.JMS架構
如果客戶端和服務器端同一個JBOSS,則通過JCA作通訊,通過調整deploy/jca-jboss-beans.xml中的WorkManagerThreadPool的參數來調優,
如果不在一個JBOSS內,則通過遠程框架進行通訊,通過調整deploy\messaging\remoting-bisocket-service.xml中的org.jboss.remoting.transport.Connector里的參數大小來調優
3.調優JBoss Messaging Connectionfactory
deploy\messaging\connection-factories-service.xml
4.調優JBoss Messaging destinations
在deploy/messaging中增加*–service.xml文件,從而增加MBEAN,來增加隊列,再調整其參數
5.HornetQ
是JBOSS 6.0之后的JMS服務器,沒有依賴于任何JBOSS包,可以嵌于任何程序中。
調優主要針對deploy/hornetq/hornetq-configuration.xml文件中的journal和transport參數
journal:journal-directory-存放message的地方,如果與其他文件夾共享,則會降低性能;journal-min-files:生成文件的個數,如果發現新文件建立的次數非常頻繁,則考慮加大此數值來避免
6.JMS調優基本原則
減少message的大小;使用DUPS_OK_ACKNOWLEDGE;重用JMS資源,如connections, sessions, consumers, and producers;可以不持久化message的就不持久化。
持久層的調優數據庫設計調優
1.減少表所占的空間
這樣IO讀速度會加快,更少的內存;列的數據類型選少的;表設計要正規化(如果是報表類型的程序則非正規化的表速度要好)
2.數據庫分割
如果某個表數據量太大,可將此表按某種邏輯分割成若干個小表,如按月份分成不同的表,不同月份的數據就放于不同的表中;
如果某個表中字段數太多,可將某些字段分組,不同的組建不同的表,如將BLOB類型的字段分割到新表中;
3.增加索引
對查詢中用得比較锪WHERE字段做索引,索引數據是被抽出來,進行排序后單獨存放的,如果不加索引,排序的動作只能在SQL被執行的時候做;
如果做了索引的字段被修改,則該字段的索引同樣也要被修改,重新排序,這也會帶來性能問題,因此一個表中最多只能放4-5個索引;
但如果這個表是只讀的,則索引可以隨意增加;
如果有組合索引,則UNIQUE的,值比較大的字段放在前面會比較好;
索引可以加在HIBERNATE的注釋中
JDBC的調優
1. 使用鏈接池來鏈接數據庫
數據鏈接的建立和關閉是一個非常昂貴的操作,能重用就重用,客戶端從PreparedStatement Cache中取得對象,PreparedStatement再從鏈接池中取得鏈接,從而得以進行對數據庫的操作
2.設置正確的fetch大小
如果設置了fetch大小為100,則JDBC會從數據庫中取回100條記錄,這樣從ResultSet中讀取next()是,是從內存中返回數據,超過了100再從數據庫中取100以備用;
此數值一般設為當次查詢總量的一半或1/4,但如果隨便設高,性能反而下降;
JBOSS中設置全局大小:<connection-property name="defaultFetchSize">50</
connection-property>
3.INSERT和UPDATE使用批量操作
4.使用PreparedStatement而不使用Statement
PreparedStatement能避免SQL語句重復解釋;使用PreparedStatement cache來緩存PreparedStatement對象
5.JDBC網絡調優
<connection-property name="tcpSndBuf">65534</connection-property>
<connection-property name="tcpRcvBuf">65534</connection-property>
<connection-property name="tcpNoDelay">true</connection-property>JPA/HIBERNATE調優
使用JDBC的限制:
由于是使用了原生的SQL語句,但不同的數據庫SQL語句也是不同的,如果換數據庫的時候SQL語句改動量大;
多表關聯時,需維護JAVA OBJECT與數據表的對應關系;
加緩存時,工作量也比較大。
JPA與HIBERNATE的區別:JPA是JAVA的一個標準,HIBERNATE是JPA的一個實現
1.優化對象獲取
HIBERNATE的N+1總量,如果有兩個表是一對多的關系,查詢父表的時候,子表的數據是不會被查出來的,直到調用查詢子表的方法時子表的數據才被查出來,因此而多出一個SQL語句
使用LEFT OUTER JOIN來達到只用一個SQL語句就查出父表和子表的數據
Query q = entityManager.createQuery("from Customer c left outer join
fetch c.items order by c.id");2.以分頁的方式限制一次性獲取數據的數量
q.setFirstResult(page*100).setMaxResults(100);3.不能同時使用分頁和FETCH的方式
HIBERNATE的分頁,是首先取出所有的數據再在內存中分頁,以避免不同數據庫中分頁語句的不同
4.使用BatchSize
@BatchSize(size = 50)
加載相關聯的實體集合的個數,注意個數的對象是集合,不是集合里的單個元素
5.使用named queries作查詢
這樣會使用到PreparedStatement中的綁定參數
6.使用批量更新與插入
Session session =HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();

for (int index = 0; index <1000;index++)
{
Person person = new Person();
book.setCountry("Usa");
book.setCity("NY");
person.setName("Inhabitant n." + index);
session.save(person);
// Flush every 50 records

if (index % 50== 0)
{
session.flush();
session.clear();
}
}
session.getTransaction().commit();
session.close();7.使用HIBERNATE CACHE
一級緩存,在SESSION關閉前都可以使用;
二級緩存,HIBERNATE使用第三方CACHE框架來做緩存
<property name="hibernate.cache.use_second_level_cache"
value="true"/>
<property name="hibernate.cache.region.factory_class"
value="org.hibernate.cache.jbc2.
JndiMultiplexedJBossCacheRegionFactory"/>
<property name="hibernate.cache.region.jbc2.cachefactory"
value="java:CacheManager"/>
<property name="hibernate.cache.region.jbc2.cfg.entity"
value="mvcc-entity"/>
<property name="hibernate.cache.region.jbc2.cfg.collection"
value="mvcc-entity"/>啟用緩存
@Entity
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL, region =
"customers")

public class Customer implements Serializable
{
}查詢緩存
<property name="hibernate.cache.use_query_cache" value="true"/>啟用查詢緩存
@NamedQueries(


{
@NamedQuery(
name = "findCustomersByName",
query = "FROM Customer c WHERE c.name = :name",

hints =
{ @QueryHint(name = "org.hibernate.cacheable", value =
"true") }
)使用緩存的策略:靜態數據可以考慮,但查詢和更新頻率很高的、查詢條件非常復雜的不建議用