日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于 SAP CloudFoundry 应用的 Resilience

發布時間:2023/12/19 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于 SAP CloudFoundry 应用的 Resilience 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Introduce Resilience to your Application

Step 1: Resilience

考慮以下情況:您正在開發一個云應用程序來為您的客戶提供服務。為了讓您的客戶滿意,您當然對實現應用程序的最高可用性感興趣。

然而,可能跨越多個服務的云應用程序本質上是復雜的。因此,可以安全地假設某事某處會在某個時間點失敗。例如,對數據庫的調用可能會失敗并導致應用程序的一部分失敗。如果應用程序的其他部分依賴于失敗的部分,這些部分也會失敗。因此,單個故障可能會級聯整個系統并破壞它。這對于多租戶應用程序尤其重要,其中應用程序的單個實例為多個客戶提供服務。典型的 S/4HANA 多租戶應用程序涉及許多下游服務,例如本地 S/4HANA ERP 系統。

讓我們看一個具體的例子:假設您的云應用程序依賴于 30 個系統,每個系統的“完美”可用性為 99.99%。這意味著每個服務每月有 4.32 分鐘不可用(43200 分鐘 * (1 – 0.9999) = 4.32 分鐘)。

現在假設故障是級聯的,因此一項服務不可用意味著整個應用程序變得不可用。鑒于上面使用的等式,現在的情況是這樣的:

43200 分鐘 * (1 – 0.9999^30) = 43200 分鐘 * (1 – 0.997) = 129.6 分鐘

因此,您的多租戶應用程序每個月對于每個客戶來說都無法使用超過兩個小時!

為了避免這種情況,我們需要為應用程序配備處理故障的能力。如果應用程序可以處理故障,則稱為彈性。因此,彈性是我們實現可用性的手段。

Step 2: Resilience4j

SAP Cloud SDK 現在基于 Resilience4j 庫構建,以便為您的云應用程序提供彈性。在之前的 2.x 版本中,我們使用了 Hystrix 庫,它現在已經處于維護模式有一段時間了。

Resilience4j 帶有許多模塊來保護您的應用程序免受故障。最重要的是超時、隔板和斷路器。

超時:Resilience4j 允許為每個遠程服務設置自定義超時持續時間。如果遠程服務的響應時間超過指定的超時時間,則認為遠程服務調用失敗。該值應根據遠程服務的平均響應時間進行調整。

隔板:這些允許限制對遠程服務的并發請求數。如果并發傳入請求的數量超過配置的閾值,則稱該隔板已飽和。在這種情況下,在現有請求完成之前,將自動停止進一步的請求。

斷路器:Resilience4j 使用斷路器模式來確定遠程服務當前是否可用。斷路器默認關閉。如果遠程服務調用失敗太多次,Resilience4j 將打開/跳閘斷路器。這意味著應該對同一遠程服務進行的任何進一步調用都將自動停止。 Resilience4j 將定期檢查服務是否再次可用,并相應地再次關閉打開的斷路器。有關斷路器模式的更多信息,請查看 Martin Fowler 的這篇文章。

此外,SAP Cloud SDK 使您能夠提供回退功能。因此,如果調用失敗,例如因為隔板飽和或斷路器斷開/跳閘,SDK 將檢查是否實現了回退并自動調用它。因此,即使服務不可用,您仍然可以提供一些有用的結果,例如通過提供緩存數據。

如果您想更深入地了解內部工作原理,請查看 Resilience4j 用戶指南。

Step 3: Make your OData call resilient

既然我們已經介紹了為什么彈性很重要,現在是時候將它引入您的應用程序了。 在上一個教程中,您創建了一個簡單的 servlet,它使用 SDK 的虛擬數據模型 (VDM) 和其他有用的抽象來從 ERP 系統中檢索業務合作伙伴。 為了使此 VDM 調用具有彈性,您必須使用 SAP Cloud SDK 提供的 ResilienceDecorator 類包裝代碼。

同時,您還將 VDM 調用本身分離到另一個類中,以便在以后的教程中具有更好的可讀性和更容易的維護。 請注意,從 SAP Cloud SDK 版本 3 開始,不再需要單獨的類來實現彈性。 您還可以直接向現有的 BusinessPartnerServlet 類添加彈性。

所以首先創建以下類:

./application/src/main/java/com/sap/cloud/sdk/tutorial/GetBusinessPartnersCommand.java

package com.sap.cloud.sdk.tutorial;import org.slf4j.Logger; import org.slf4j.LoggerFactory;import java.time.Duration; import java.util.Collections; import java.util.List;import com.sap.cloud.sdk.cloudplatform.resilience.ResilienceConfiguration; import com.sap.cloud.sdk.cloudplatform.resilience.ResilienceDecorator; import com.sap.cloud.sdk.cloudplatform.resilience.ResilienceIsolationMode; import com.sap.cloud.sdk.cloudplatform.resilience.ResilienceRuntimeException; import com.sap.cloud.sdk.datamodel.odata.client.exception.ODataException; import com.sap.cloud.sdk.datamodel.odata.helper.Order;import com.sap.cloud.sdk.s4hana.connectivity.ErpHttpDestination; import com.sap.cloud.sdk.s4hana.datamodel.odata.namespaces.businesspartner.AddressEmailAddress; import com.sap.cloud.sdk.s4hana.datamodel.odata.namespaces.businesspartner.BusinessPartner; import com.sap.cloud.sdk.s4hana.datamodel.odata.namespaces.businesspartner.BusinessPartnerAddress; import com.sap.cloud.sdk.s4hana.datamodel.odata.services.BusinessPartnerService; import com.sap.cloud.sdk.s4hana.datamodel.odata.services.DefaultBusinessPartnerService;public class GetBusinessPartnersCommand {private static final Logger logger = LoggerFactory.getLogger(GetBusinessPartnersCommand.class);// TODO: uncomment the lines below and insert your API key, if you are using the sandbox service// private static final String APIKEY_HEADER = "apikey";// private static final String SANDBOX_APIKEY = "";private static final String CATEGORY_PERSON = "1";private final ErpHttpDestination destination;private final BusinessPartnerService businessPartnerService;private final ResilienceConfiguration myResilienceConfig;public GetBusinessPartnersCommand(ErpHttpDestination destination) {this(destination, new DefaultBusinessPartnerService());}public GetBusinessPartnersCommand(ErpHttpDestination destination, BusinessPartnerService service) {this.destination = destination;businessPartnerService = service;myResilienceConfig = ResilienceConfiguration.of(BusinessPartnerService.class).isolationMode(ResilienceIsolationMode.TENANT_AND_USER_OPTIONAL).timeLimiterConfiguration(ResilienceConfiguration.TimeLimiterConfiguration.of().timeoutDuration(Duration.ofMillis(10000))).bulkheadConfiguration(ResilienceConfiguration.BulkheadConfiguration.of().maxConcurrentCalls(20));}public List<BusinessPartner> execute() {return ResilienceDecorator.executeSupplier(this::run, myResilienceConfig, e -> {logger.warn("Fallback called because of exception.", e);return Collections.emptyList();});}private List<BusinessPartner> run() {try {return businessPartnerService.getAllBusinessPartner().select(BusinessPartner.BUSINESS_PARTNER,BusinessPartner.LAST_NAME,BusinessPartner.FIRST_NAME,BusinessPartner.IS_MALE,BusinessPartner.IS_FEMALE,BusinessPartner.CREATION_DATE,BusinessPartner.TO_BUSINESS_PARTNER_ADDRESS.select(BusinessPartnerAddress.CITY_NAME,BusinessPartnerAddress.COUNTRY,BusinessPartnerAddress.TO_EMAIL_ADDRESS.select(AddressEmailAddress.EMAIL_ADDRESS))).filter(BusinessPartner.BUSINESS_PARTNER_CATEGORY.eq(CATEGORY_PERSON)).orderBy(BusinessPartner.LAST_NAME, Order.ASC).top(200)// TODO: uncomment the line below, if you are using the sandbox service// .withHeader(APIKEY_HEADER, SANDBOX_APIKEY).executeRequest(destination);} catch (ODataException e) {throw new ResilienceRuntimeException(e);}} }

要使用 ResilienceDecorator,您至少需要做兩件事:

您希望以彈性方式執行的代碼。它可以是 Supplier、Callable、Supplier、方法引用或簡單的 lambda 函數。您可能已經注意到,該示例僅采用基于 VDM 的代碼調用上一教程中的 OData 服務,并將其放入單獨的 run() 方法中。 ResilienceDecorator 提供的方法可以簡單地包裝所提供的函數并返回一個新函數(decorateSupplier、decorateCallable 等),以及也立即開始執行該函數的方法(executeSupplier、executeCallable 等)。這里 executeSupplier 與基于 VDM 的代碼的方法引用一起使用。

帶有標識符參數集的 ResilienceConfiguration 實例。這里的示例使用類引用,但也可以使用字符串標識符。除了強制標識符參數外,SAP Cloud SDK 還帶有默認的彈性配置,因此您無需自行執行任何其他配置。在大多數情況下,默認配置就足夠了。但是,如果您需要更改彈性配置,您可以在 SAP Cloud SDK Javadoc 中找到有關此主題的更多信息

這是自定義彈性配置的示例。這里隔離模式設置為可選租戶+用戶,隔板最大并發調用數為20,執行超時為10000毫秒。

myResilienceConfig = ResilienceConfiguration.of(BusinessPartnerService.class).isolationMode(ResilienceIsolationMode.TENANT_AND_USER_OPTIONAL).timeLimiterConfiguration(ResilienceConfiguration.TimeLimiterConfiguration.of().timeoutDuration(Duration.ofMillis(10000))).bulkheadConfiguration(ResilienceConfiguration.BulkheadConfiguration.of().maxConcurrentCalls(20));

此外,ResilienceDecorator 的decorate… 和execute… 方法支持可選的第三個參數作為回退函數,以防遠程服務調用失敗。 在這種情況下,使用返回空列表的 lambda 函數。 您還可以提供靜態數據或檢查對此調用的響應是否已被緩存。 最佳實踐是至少記錄提供的 Throwable。

更新您的彈性配置以匹配上述配置。 現在您有了一個工作命令,您需要調整您的 BusinessPartnerServlet 以使用新創建的命令:

./application/src/main/java/com/sap/cloud/sdk/tutorial/BusinessPartnerServlet.java

package com.sap.cloud.sdk.tutorial;import com.google.gson.Gson; import org.slf4j.Logger; import org.slf4j.LoggerFactory;import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List;import com.sap.cloud.sdk.cloudplatform.connectivity.DestinationAccessor;import com.sap.cloud.sdk.s4hana.connectivity.ErpHttpDestination; import com.sap.cloud.sdk.s4hana.connectivity.DefaultErpHttpDestination; import com.sap.cloud.sdk.s4hana.datamodel.odata.namespaces.businesspartner.BusinessPartner;@WebServlet("/businesspartners") public class BusinessPartnerServlet extends HttpServlet {private static final long serialVersionUID = 1L;private static final Logger logger = LoggerFactory.getLogger(BusinessPartnerServlet.class);private static final String DESTINATION_NAME = "MyErpSystem";@Overrideprotected void doGet(final HttpServletRequest request, final HttpServletResponse response)throws ServletException, IOException {try {final ErpHttpDestination destination = DestinationAccessor.getDestination(DESTINATION_NAME).asHttp().decorate(DefaultErpHttpDestination::new);final List<BusinessPartner> businessPartners =new GetBusinessPartnersCommand(destination).execute();response.setContentType("application/json");response.getWriter().write(new Gson().toJson(businessPartners));} catch (final Exception e) {logger.error(e.getMessage(), e);response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);response.getWriter().write(e.getMessage());e.printStackTrace(response.getWriter());}} }

總結

以上是生活随笔為你收集整理的关于 SAP CloudFoundry 应用的 Resilience的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。