CUBA:如何准备上线
目錄
- CUBA:如何準(zhǔn)備上線
- 編碼準(zhǔn)則
- 使用服務(wù)(Services)
- 使用無狀態(tài)
- 使用日志
- 異常處理
- 環(huán)境相關(guān)的配置
- 使用恰當(dāng)?shù)姆?wù)實(shí)現(xiàn)
- 將配置參數(shù)外部化
- 添加網(wǎng)絡(luò)超時(shí)處理
- 數(shù)據(jù)庫準(zhǔn)則
- 生成特定環(huán)境的數(shù)據(jù)庫腳本
- 考慮多租戶
- 安全性考慮
- 安全的編碼
- 準(zhǔn)則 3-2 / INJECT-2: 避免動(dòng)態(tài) SQL
- 準(zhǔn)則 5-1 / INPUT-1: 驗(yàn)證輸入
- 保護(hù)個(gè)人數(shù)據(jù)安全
- 修改或者禁用默認(rèn)用戶和角色
- 導(dǎo)出角色至生產(chǎn)環(huán)境
- 配置應(yīng)用程序
- 日志配置
- 在群集配置中運(yùn)行
- 計(jì)劃任務(wù)
- 分布式緩存
- 結(jié)論
CUBA:如何準(zhǔn)備上線
“在我電腦上是好的呢!”現(xiàn)在看來,這句話更像是調(diào)侃開發(fā)人員的一個(gè)段子,但是“開發(fā)環(huán)境與生產(chǎn)環(huán)境”之間的矛盾依然存在。作為開發(fā)者,你需要記住,你寫的應(yīng)用總會(huì)有在生產(chǎn)環(huán)境上線的一天。在本文中,我們將討論一些 CUBA 的特性,能幫助你避免在應(yīng)用程序上線時(shí)遇到問題。
編碼準(zhǔn)則
使用服務(wù)(Services)
幾乎每一個(gè) CUBA 應(yīng)用程序都會(huì)實(shí)現(xiàn)一些業(yè)務(wù)邏輯算法。實(shí)現(xiàn)業(yè)務(wù)邏輯的最佳實(shí)踐就是所有的業(yè)務(wù)代碼都在 CUBA 服務(wù)(CUBA Services)中實(shí)現(xiàn)。所有其他的類,包括界面控制器、應(yīng)用程序監(jiān)聽器等等,應(yīng)當(dāng)將業(yè)務(wù)邏輯全部交由服務(wù)來代理執(zhí)行。這個(gè)方式的好處是:
請(qǐng)注意,業(yè)務(wù)邏輯中一般會(huì)包括條件、循環(huán)等。在理想情況下,對(duì)服務(wù)的調(diào)用應(yīng)該是單線的。比如,我們假設(shè)在控制器中有如下代碼:
Item item = itemService.findItem(itemDate); if (item.isOld()) {itemService.doPlanA(item); } else {itemService.doPlanB(item); }如果你看到這種代碼,可以考慮在 itemService 服務(wù)中創(chuàng)建一個(gè)單獨(dú)的方法 processOldItem(Date date) ,將這段分支判斷邏輯遷移到服務(wù)中實(shí)現(xiàn),因?yàn)檫@段代碼看上去更像是業(yè)務(wù)邏輯的一部分。
由于界面和 API 可能會(huì)是不同的團(tuán)隊(duì)開發(fā),所以保持業(yè)務(wù)邏輯只存在一個(gè)地方可以避免生產(chǎn)環(huán)境中應(yīng)用程序行為的不一致。
使用無狀態(tài)
當(dāng)開發(fā) web 應(yīng)用程序時(shí),需要時(shí)刻記得將會(huì)有多個(gè)用戶同時(shí)使用你的程序。在代碼中,意味著有些代碼會(huì)被多個(gè)線程同時(shí)執(zhí)行。幾乎所有的應(yīng)用程序組件,比如服務(wù)、bean 以及事件監(jiān)聽器都會(huì)受到多線程執(zhí)行的影響。這里的最佳實(shí)踐就是讓組件保持無狀態(tài)。 也就是說不要引入共享的可變類成員。 使用局部變量并將會(huì)話級(jí)特定的信息保留在用戶之間不共享的應(yīng)用程序存儲(chǔ)中。 例如,可以在用戶會(huì)話中保留少量可序列化的數(shù)據(jù)。
如果需要共享更多的數(shù)據(jù),可以使用數(shù)據(jù)庫或者專門的內(nèi)存共享存儲(chǔ),比如 Redis。
使用日志
有時(shí),生產(chǎn)環(huán)境會(huì)出一些問題。當(dāng)問題產(chǎn)生時(shí),很難搞清楚到底是什么引起的問題,因?yàn)闆]辦法在生產(chǎn)環(huán)境調(diào)試。所以為了使你自己、團(tuán)隊(duì)以及支撐團(tuán)隊(duì)將來的工作更加輕松,為了能明白問題怎么發(fā)生的,以便能重現(xiàn),最好在應(yīng)用程序中添加適量的日志。
此外,日志還扮演了被動(dòng)監(jiān)測的角色。在應(yīng)用程序重啟、升級(jí)或者重新配置之后,管理員通常通過查看日志確保所有的程序都啟動(dòng)成功。
日志還能幫助解決可能不是在你的應(yīng)用程序中發(fā)生的問題,而是應(yīng)用程序集成的其他服務(wù)中。 例如,要弄清楚為什么支付網(wǎng)關(guān)會(huì)拒絕某些交易,可能需要記錄所有數(shù)據(jù),然后在與支撐團(tuán)隊(duì)溝通時(shí)提供這些數(shù)據(jù)。
CUBA 使用了經(jīng)過驗(yàn)證的 slf4j 庫作為日志切面和 logback 實(shí)現(xiàn)。 只需要向類代碼中注入日志工具類,就可以用了:
@Inject private Logger log;然后直接調(diào)用:
log.info("Transaction for the customer {} has succeeded at {}", customer, transaction.getDate());請(qǐng)記住,日志消息需要有意義并包含足夠的信息以便了解在應(yīng)用程序中到底發(fā)生了什么。
還有,CUBA 自帶性能統(tǒng)計(jì)日志,所以你可以看到應(yīng)用程序?qū)Ψ?wù)器資源的消耗情況。當(dāng)收到用戶抱怨應(yīng)用程序很慢時(shí),這些日志非常有用,用它們能更快的找到性能瓶頸。
異常處理
異常是非常重要的,在應(yīng)用程序發(fā)生錯(cuò)誤時(shí),它們能提供非常有價(jià)值的信息。因此,第一條規(guī)則就是在代碼中永遠(yuǎn)不要忽視任何異常。使用 log.error() 方法創(chuàng)建一個(gè)有含義的消息,添加上下文和 stack trace。這個(gè)消息是你能用來定位錯(cuò)誤的唯一信息。
如果你有編碼規(guī)范,那么添加一章關(guān)于錯(cuò)誤處理的章節(jié)吧。
我們看一個(gè)例子 - 上傳一張用戶的資料照片至應(yīng)用程序。這個(gè)資料照片會(huì)使用上傳 API 服務(wù)并存儲(chǔ)在 CUBA 的文件存儲(chǔ)中。
如果不處理異常,代碼是這樣:
try {fileUploadingAPI.putFileIntoStorage(uploadField.getFileId(), fd); } catch (Exception e) {}如果發(fā)生了錯(cuò)誤,鬼才會(huì)知道。用戶會(huì)很奇怪,我的照片怎么上不去?
下面這個(gè)好一些,但是還不理想:
日志中會(huì)保存一條錯(cuò)誤信息,但是我們只捕獲了特定的異常類。也沒有提供有關(guān)上下文的信息:文件的名稱是什么,誰曾嘗試上傳文件。 而且,由于沒有 stack trace 的信息,因此很難找到異常發(fā)生的位置。 還有,用戶根本不會(huì)知道這里發(fā)生了錯(cuò)誤。
下面這個(gè)應(yīng)該是一個(gè)比較好的方式:
try {fileUploadingAPI.putFileIntoStorage(uploadField.getFileId(), fd); } catch (FileStorageException e) {throw new RuntimeException("Error saving file to FileStorage", e); }我們知道錯(cuò)誤是什么,也沒有丟失原始異常,添加了一條有意義的消息文本。 調(diào)用方法將收到有關(guān)異常的通知。 我們可以將當(dāng)前用戶名以及上傳文件名添加到消息中,以增加更多上下文數(shù)據(jù)。 這是 CUBA Web 模塊的示例。
在 CUBA 應(yīng)用程序中,由于其分布式特性,你可能在 Core 模塊和 Web 模塊具有不同的異常處理規(guī)則。 文檔中有一個(gè)關(guān)于異常處理的特殊部分。 在實(shí)現(xiàn)異常處理時(shí),建議先閱讀該章節(jié)。
環(huán)境相關(guān)的配置
開發(fā)應(yīng)用程序時(shí),請(qǐng)?jiān)囋噷?yīng)用中與環(huán)境相關(guān)的部分獨(dú)立出來,然后試用功能開關(guān)和配置文件根據(jù)環(huán)境切換這些部分的功能。
使用恰當(dāng)?shù)姆?wù)實(shí)現(xiàn)
CUBA 中的任何服務(wù)都包含兩個(gè)部分:接口(服務(wù) API)及其實(shí)現(xiàn)。有時(shí)候,服務(wù)的實(shí)現(xiàn)依賴于部署環(huán)境。我們拿文件存儲(chǔ)服務(wù)作為例子。
在 CUBA 中,可以使用文件存儲(chǔ)來保存發(fā)送至應(yīng)用程序的文件,然后可以在服務(wù)中使用這些文件。其默認(rèn)實(shí)現(xiàn)是使用服務(wù)器上的本地文件系統(tǒng)保存文件。
但是,當(dāng)你部署應(yīng)用程序至生產(chǎn)服務(wù)器時(shí),如果使用了云環(huán)境或者集群部署,這個(gè)實(shí)現(xiàn)就不一定能正常工作了。
如果要使用針對(duì)環(huán)境的不同服務(wù)實(shí)現(xiàn),CUBA 支持運(yùn)行時(shí)配置,可以根據(jù)啟動(dòng)參數(shù)或者環(huán)境變量使用特定的服務(wù)實(shí)現(xiàn)。
對(duì)于上面這個(gè)例子,如果我們想用 Amazon S3 作為生產(chǎn)環(huán)境文件存儲(chǔ)的實(shí)現(xiàn),可以用下面的方式指定這個(gè) bean:
<beans profile="prod"><bean name="cuba_FileStorage" class="com.haulmont.addon.cubaaws.s3.AmazonS3FileStorage"/></beans>然后,在設(shè)置了下面這個(gè)屬性時(shí),會(huì)自動(dòng)啟用基于 S3 的實(shí)現(xiàn):
spring.profiles.active=prod因此,當(dāng)開發(fā) CUBA 應(yīng)用程序時(shí),嘗試將環(huán)境相關(guān)的服務(wù)先定義出來,然后為每種環(huán)境啟用適當(dāng)?shù)姆?wù)實(shí)現(xiàn)。不要寫下面這種代碼:
If (“prod”.equals(getEnvironment())) {executeMethodA(); } else {executeMethodB(); }此時(shí),需要實(shí)現(xiàn)一個(gè)單獨(dú)服務(wù) myService 帶有一個(gè)方法 executeMethod() 和兩個(gè)實(shí)現(xiàn)類,然后通過配置文件來配置。這樣在調(diào)用此服務(wù)的地方,只有:
myService.executeMethod();干凈、簡單、易維護(hù)。
將配置參數(shù)外部化
如果可能的話,將應(yīng)用程序的配置提取到屬性文件中。 如果參數(shù)將來可以修改(即使概率很小),也需要將其外部化。代碼中應(yīng)盡量避免將連接URL、主機(jī)名等作為純字符串,并且千萬不要到處復(fù)制粘貼。 在代碼中更改硬編碼(hardcode)值的成本要高得多。 郵件服務(wù)器地址、用戶的照片縮略圖大小、沒有網(wǎng)絡(luò)連接時(shí)的重試次數(shù),等等所有這類配置都是需要外部化的屬性。 使用配置接口,并在你的類中注入即可獲取配置值。
使用運(yùn)行時(shí)配置將環(huán)境相關(guān)的屬性放在單獨(dú)的文件中。
還是拿支付網(wǎng)關(guān)舉個(gè)例子。 首先,我們不會(huì)在開發(fā)過程中使用真正的鈔票來測試功能。 因此,會(huì)有一個(gè)用于本地環(huán)境的網(wǎng)關(guān)存根,一個(gè)在網(wǎng)關(guān)端用于預(yù)發(fā)布測試環(huán)境的測試 API 和一個(gè)用于生產(chǎn)環(huán)境的真實(shí)網(wǎng)關(guān)。 顯然,這些環(huán)境的網(wǎng)關(guān)地址不同。
別這么寫代碼:
If (“prod”.equals(getEnvironment())) {gatewayHost = “gateway.payments.com”; } else if (“test”.equals(getEnvironment())) {gatewayHost = “testgw.payments.com”; } else {gatewayHost = “l(fā)ocalhost”; } connectToPaymentsGateway(gatewayHost);而是,定義三個(gè)屬性文件:dev-app.properties、test-app.properties 以及 prod-app.properties,分別在其中定義 payment.gateway.host.name 的值。之后,在項(xiàng)目中添加一個(gè)配置接口:
@Source(type = SourceType.DATABASE) public interface PaymentGwConfig extends Config {@Property("payment.gateway.host.name")String getPaymentGwHost(); }然后可以在代碼中注入該接口并使用:
@Inject PaymentGwConfig gwConfig;// 其它代碼connectToPaymentsGateway(gwConfig.getPaymentGwHost());這樣的話,代碼會(huì)很簡單,所有的設(shè)置都在屬性文件中,如果環(huán)境有變,也不需要在代碼中查找了。
添加網(wǎng)絡(luò)超時(shí)處理
開發(fā)時(shí),要始終認(rèn)為通過網(wǎng)絡(luò)進(jìn)行的服務(wù)調(diào)用不可靠。當(dāng)前用于 Web 服務(wù)調(diào)用的大多數(shù)第三方庫都基于同步阻塞通信模型。也就是說,如果從主執(zhí)行線程調(diào)用 Web 服務(wù),則應(yīng)用程序?qū)和V钡绞盏巾憫?yīng)為止。
即使在單獨(dú)的線程中執(zhí)行 Web 服務(wù)調(diào)用,由于網(wǎng)絡(luò)超時(shí),該線程也有可能永遠(yuǎn)無法恢復(fù)執(zhí)行。
有兩種類型的超時(shí):連接超時(shí)和數(shù)據(jù)讀取超時(shí)。
在應(yīng)用程序中,這些超時(shí)類型應(yīng)分開處理。我們還是看看支付網(wǎng)關(guān)的例子。此時(shí),讀取超時(shí)可能明顯長于連接超時(shí)。銀行交易可以處理很長的時(shí)間,數(shù)十秒,最多幾分鐘。但是連接應(yīng)該很快,那么這里我們可以將連接超時(shí)設(shè)置為一個(gè)稍長的時(shí)間,比如10秒。
超時(shí)時(shí)限的配置可以移至屬性文件,這基本上是一個(gè)最典型的例子了。為需要通過網(wǎng)絡(luò)交互的所有服務(wù)設(shè)置該值。以下是服務(wù)bean定義的示例:
<bean id="paymentGwConfig" class="com.global.api.serviceConfigs.GatewayConfig"><property name="connectionTimeout" value="${xxx.connectionTimeoutMillis}"/><property name="readTimeout" value="${xxx.readTimeoutMillis}"/></bean>在你的代碼中,需要包含一段專門用來處理超時(shí)的代碼。
數(shù)據(jù)庫準(zhǔn)則
數(shù)據(jù)庫是幾乎所有應(yīng)用程序的核心。 在部署和更新生產(chǎn)環(huán)境時(shí),不破壞數(shù)據(jù)庫是非常重要的。 除此之外,工作負(fù)載方面,開發(fā)人員工作站上的數(shù)據(jù)庫顯然與生產(chǎn)服務(wù)器不同。 因此,可能要實(shí)施以下描述的一些做法。
生成特定環(huán)境的數(shù)據(jù)庫腳本
CUBA 中,我們能生成創(chuàng)建和更新應(yīng)用程序數(shù)據(jù)庫的 SQL 腳本。在生產(chǎn)環(huán)境第一次數(shù)據(jù)庫創(chuàng)建之后,只要數(shù)據(jù)模型發(fā)生改動(dòng),CUBA 框架都會(huì)生成更新腳本。
文檔中有一個(gè)章節(jié)專門介紹生產(chǎn)環(huán)境的數(shù)據(jù)庫更新。請(qǐng)?jiān)诘谝淮尾渴鹕a(chǎn)環(huán)境之前仔細(xì)閱讀。
最終建議,在更新數(shù)據(jù)庫之前先做備份。這樣做能節(jié)省很多時(shí)間,并且也不用擔(dān)心出問題。
考慮多租戶
如果你的項(xiàng)目是一個(gè)多租戶項(xiàng)目,請(qǐng)?jiān)陧?xiàng)目開始時(shí)就將多租戶的場景設(shè)計(jì)好。
CUBA 通過擴(kuò)展插件支持多租戶,該擴(kuò)展會(huì)引入一些應(yīng)用程序數(shù)據(jù)模型以及數(shù)據(jù)庫查詢語句邏輯的改動(dòng)。比方說,對(duì)于租戶場景下的實(shí)體,會(huì)添加 tanantId 這一列。因此,所有查詢這些實(shí)體的查詢語句都被隱式的做了修改,以便能使用該列作為查詢條件。也就是說,如果你需要寫自定義 SQL 查詢,需要考慮此列的存在。
請(qǐng)注意,由于上面提到的特定功能,向在生產(chǎn)環(huán)境中運(yùn)行的應(yīng)用程序添加多租戶功能可能很棘手。 為了簡化遷移,請(qǐng)將所有自定義查詢保留在同一應(yīng)用程序?qū)又?#xff0c;最好保留在服務(wù)中或單獨(dú)的數(shù)據(jù)訪問層中。
安全性考慮
對(duì)于可以被多個(gè)用戶訪問的應(yīng)用程序,安全性起著重要的作用。 為避免數(shù)據(jù)泄漏、未經(jīng)授權(quán)的訪問等,需要認(rèn)真考慮安全性。下面會(huì)介紹一些原則,這些原則可以幫助改善系統(tǒng)的安全性。
安全的編碼
提到安全性,首先就要寫出能阻止問題產(chǎn)生的代碼。 可以在此處找到Oracle提供的有關(guān)安全編碼的參考。 下面我們介紹其中的一些(也許很明顯的)建議。
準(zhǔn)則 3-2 / INJECT-2: 避免動(dòng)態(tài) SQL
大家都知道,動(dòng)態(tài)創(chuàng)建的 SQL 語句(帶有不受信任的輸入)容易受到命令注入的攻擊。 在 CUBA 中,你很可能需要執(zhí)行 JPQL 語句,因此,也請(qǐng)避免使用動(dòng)態(tài) JPQL。 如果需要添加參數(shù),請(qǐng)使用適當(dāng)?shù)念惡驼Z句語法:
try (Transaction tx = persistence.createTransaction()) {// get EntityManager for the current transactionEntityManager em = persistence.getEntityManager();// create and execute QueryQuery query = em.createQuery("select sum(o.amount) from sample_Order o where o.customer.id = :customerId");query.setParameter("customerId", customerId);result = (BigDecimal) query.getFirstResult();// commit transactiontx.commit(); }準(zhǔn)則 5-1 / INPUT-1: 驗(yàn)證輸入
在使用前,必須驗(yàn)證來自不受信任來源的輸入。 惡意的輸入可能會(huì)導(dǎo)致問題,無論是通過方法參數(shù)還是外部流。 比如整數(shù)值溢出和通過在文件名中包含“ …/”序列的目錄遍歷攻擊。 在CUBA中,除了在代碼中檢查之外,還可以在 GUI 中使用驗(yàn)證器。
以上只是安全編碼原理的幾個(gè)簡單例子。 請(qǐng)仔細(xì)閱讀該指南,能在多方面改善你的代碼安全性。
保護(hù)個(gè)人數(shù)據(jù)安全
由于法律要求,某些個(gè)人信息應(yīng)受到保護(hù)。 在歐洲,有通用數(shù)據(jù)保護(hù)條例(GDPR),在美國的醫(yī)療應(yīng)用中,有健康保險(xiǎn)攜帶和責(zé)任法案(HIPAA)要求等,中國近年來對(duì)個(gè)人信息的保護(hù)也上升到了一個(gè)新的高度,不少公司因?yàn)樾孤秱€(gè)人隱私的問題而被調(diào)查。因此,在實(shí)施項(xiàng)目時(shí)要考慮到這一點(diǎn)。
使用 CUBA 可以設(shè)置各種權(quán)限,并使用角色和訪問組限制對(duì)數(shù)據(jù)的訪問。 在訪問組中,還可以定義各種約束,以防止未經(jīng)授權(quán)訪問個(gè)人數(shù)據(jù)。
但是訪問權(quán)限控制只是確保個(gè)人數(shù)據(jù)安全的一部分。 數(shù)據(jù)保護(hù)標(biāo)準(zhǔn)和行業(yè)特定要求還有很多。 在規(guī)劃應(yīng)用程序的體系結(jié)構(gòu)和數(shù)據(jù)模型之前,需要先了解這些要求。
修改或者禁用默認(rèn)用戶和角色
當(dāng)使用 CUBA 框架創(chuàng)建應(yīng)用程序時(shí),系統(tǒng)會(huì)創(chuàng)建兩個(gè)默認(rèn)用戶:admin 和 anonymous。最好在系統(tǒng)上到生產(chǎn)環(huán)境之后,客戶開始用之前修改這兩個(gè)用戶的默認(rèn)密碼。可以手動(dòng)修改或者在 30-....sql 的初始化腳本中添加 SQL 語句修改。
按照 CUBA 文檔的推薦步驟可以很好的配置生產(chǎn)環(huán)境需要使用的角色。
如果應(yīng)用程序需要支持復(fù)雜的組織結(jié)構(gòu),可以考慮在組織機(jī)構(gòu)級(jí)別為每個(gè)分支機(jī)構(gòu)創(chuàng)建本地管理員,而不是創(chuàng)建多個(gè)“超級(jí)管理員”。
導(dǎo)出角色至生產(chǎn)環(huán)境
在第一次部署之前,通常需要從開發(fā)環(huán)境或預(yù)發(fā)布(staging) 環(huán)境將角色和訪問組復(fù)制到生產(chǎn)服務(wù)器。 在CUBA中,可以使用內(nèi)置的管理界面來執(zhí)行此操作,而不必手動(dòng)從數(shù)據(jù)庫復(fù)制。
導(dǎo)出角色和權(quán)限配置可以使用 Administration->Roles 界面內(nèi)的導(dǎo)出按鈕。下載導(dǎo)出的文件之后,可以在生產(chǎn)環(huán)境使用該界面進(jìn)行導(dǎo)入。訪問組也有類似的按鈕操作。
配置應(yīng)用程序
生產(chǎn)環(huán)境通常與開發(fā)環(huán)境不同,應(yīng)用程序配置也會(huì)不同。也就是說,需要進(jìn)行一些其他檢查,以確保應(yīng)用程序在生產(chǎn)時(shí)能夠平穩(wěn)運(yùn)行。
日志配置
確保已針對(duì)生產(chǎn)環(huán)境正確配置了日志子系統(tǒng):日志級(jí)別已設(shè)置為所需級(jí)別(通常為 INFO),并且在應(yīng)用程序重啟時(shí)不會(huì)刪除日志。 可以參考文檔了解正確的日志設(shè)置和有用的 Logger。
如果使用 Docker,請(qǐng)使用 Docker volumes 將日志文件存儲(chǔ)在容器外部。
為了進(jìn)行正確的日志記錄分析,可以部署特殊的工具來收集、存儲(chǔ)和分析日志。 比如 ELK 家族或者 Graylog。 建議將日志記錄軟件安裝到單獨(dú)的服務(wù)器上,以避免對(duì)應(yīng)用程序造成性能影響。
在群集配置中運(yùn)行
可以將CUBA應(yīng)用程序配置為在集群中運(yùn)行。 如果決定使用此功能,則需要注意你的應(yīng)用程序架構(gòu),否則,可能會(huì)有不符合期望的行為出現(xiàn)。 下面幾點(diǎn)針對(duì)群集環(huán)境需要專門調(diào)整的最常用功能:
計(jì)劃任務(wù)
如果要在應(yīng)用程序中執(zhí)行計(jì)劃任務(wù),例如每天生成報(bào)告或每周發(fā)送電子郵件,則可以使用相應(yīng)的框架內(nèi)置功能。 但是,請(qǐng)想象一下,如果你是一位同時(shí)收到了三封相同營銷電子郵件的客戶。你會(huì)覺得開心嗎?如果計(jì)劃任務(wù)在三個(gè)群集節(jié)點(diǎn)上都執(zhí)行,則很可能會(huì)發(fā)生這種情況。 為避免這種情況,最好使用 CUBA 任務(wù)計(jì)劃程序,該程序可以創(chuàng)建單例(singleton)任務(wù)。
分布式緩存
緩存是可以提高應(yīng)用程序性能的東西。有時(shí)開發(fā)人員會(huì)嘗試把幾乎所有的數(shù)據(jù)都進(jìn)行緩存,因?yàn)楝F(xiàn)在內(nèi)存非常便宜。但是,當(dāng)應(yīng)用程序使用集群部署在多臺(tái)服務(wù)器上時(shí),將在服務(wù)器之間分配緩存,還會(huì)做緩存同步。如果同步過程發(fā)生在相對(duì)較慢的網(wǎng)絡(luò)連接上,這可能會(huì)增加響應(yīng)時(shí)間。所以在決定添加更多緩存之前(尤其是在集群環(huán)境中),需要先進(jìn)行負(fù)載測試并衡量性能。
結(jié)論
CUBA 平臺(tái)簡化了開發(fā)過程,所以很可能你會(huì)提前完成開發(fā)并開始考慮投入生產(chǎn)。可是,無論是否使用 CUBA,部署都不簡單。如果能在開發(fā)的早期階段就開始思考部署流程并遵循本文所述的簡單規(guī)則,那么你的應(yīng)用程序投入生產(chǎn)的過程應(yīng)該會(huì)很順利,所需的工作量很小,并且不會(huì)遇到嚴(yán)重的問題。
總結(jié)
以上是生活随笔為你收集整理的CUBA:如何准备上线的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jQuery添加插入元素技巧
- 下一篇: PolSARpro v6.0.2 处理S