壞代碼味道(一)

来源:https://www.cnblogs.com/OceanEyes/archive/2023/05/24/17426907.html
-Advertisement-
Play Games

### GC 優化 #### 1.防止大對象Buffer到記憶體中 **現象**:當大包請求時,YGC 耗時嚴重 **原因**:預設情況下 Zuul2 並不會緩存請求體(DirectByteBuffer),也就意味著它會先發送接收到的請求 Headers 到後端服務,之後接收到請求體再繼續發送到後端服 ...


GC 優化

1.防止大對象Buffer到記憶體中

現象:當大包請求時,YGC 耗時嚴重

原因:預設情況下 Zuul2 並不會緩存請求體(DirectByteBuffer),也就意味著它會先發送接收到的請求 Headers 到後端服務,之後接收到請求體再繼續發送到後端服務,發送請求體的時候,也不是組裝為一個完整數據之後才發,而是接收到一部分,就轉發一部分。
如果需要緩存請求體:
需要 Override needsBodyBuffered 方法, com.netflix.zuul.netty.filter.BaseZuulFilterRunner#filter
針對大包請求時,網關性能降低,體現在:網關操作會將請求體 Buffer 到用戶空間來實現提取請求體做 WAF 攔截

優化

  • 判斷大包,大包不緩存(Content-Length)

2.防止多次創建重覆對象

現象:YGC 次數多

原因
如何快速獲取 Body?Zuul 貼心的為我們提供瞭如下兩種方式,封裝在過 Request 中供開發者使用
com.netflix.zuul.message.ZuulMessageImpl#getBodyAsText
com.netflix.zuul.message.ZuulMessageImpl#getBody
但不幸的是,內部每次獲取對象繁瑣,並且 new String() 創建返回

優化
取一次,緩存在 Context 中,需要時從 Context 獲取

3.防止多次創建中間對象

現象:YGC 次數多

原因 :多次創建中間無用對象,例如:ProtobufSerializer#serialize

    @Override
    public byte[] serialize(String topic, Object data) {
        if (data == null) {
            return null;
        }
        return JSON.toJSONString(data).getBytes();
    }

優化:直接序列化成 byte,不需要先創建中間對象 String,再 getBytes()

CPU 優化

1.減少線程個數,降低上下文切換次數

現象:無關線程太多,影響記憶體(JVM+操作系統)+CPU 爭搶

原因:網關內有生產者,消費者,每個消費者都會有消費軌跡的線程池(10),網關有針對不同場景下的消費者,故會創建諸多消息軌跡線程

優化

  • 禁用消息軌跡
  • 調整消費者線程數

2.減少字元串比較次數

現象:每次請求到自定義的 Route Filter,都要通過 Loop 緩存獲取到和當前 RequestMethod 一致的 Rest API。通過火焰圖可以看出,單位時間內,該部分邏輯 CPU 計算占比高

原因

 Set<String> apis=restApiManager.getApis().stream().filter(a -> method.equalsIgnoreCase(a.getHttpMethod())).collect(Collectors.toSet());

本意是過濾掉和當前 Request Method 不一致的,但是每請求一次,都需要重覆計算過濾:O(n)

優化:O(1),改為 HashMap,Key 為 Method,Value 為 Set <String> apis,封裝統一方法獲取,RestApiManager#getApis(String method)

3.減少正則表達式計算次數

現象:API 路由需要正則匹配,最終確定需要路由的 Service。通過火焰圖可以看出,單位時間內,該部分邏輯 CPU 計算占比高

原因:API 路由需要正則匹配,最終確定需要路由的 Service

優化:通過首碼匹配,過濾掉非法的API。比如訪問:/v1/accounts/{accountId}/getAllInfo,先過濾掉非 /v1/accounts 開頭的 API,因為正則肯定不匹配

4.減少序列化

現象:序列化需要CPU運算,減少不必要的序列化場景可以提高吞吐量

原因:針對相同請求的話,WAF 里需要計算出一個簽名,減少攻擊驗證次數。

因為計算相同內容的 MD5,將對象序列化成 JSON。在高併發下序列化會大量占用 CPU。

signature = buildSignature(objectMapper.writeValueAsString(requestMessage));

優化
使用 ToString 來替換序列化:

signature = buildSignature(requestMessage.toString())

其他優化

  • 不打無用日誌,日誌需要編碼,需要 CPU 消耗
本博客為木宛城主原創,基於Creative Commons Attribution 2.5 China Mainland License發佈,歡迎轉載,演繹或用於商業目的,但是必須保留本文的署名木宛城主(包含鏈接)。如您有任何疑問或者授權方面的協商,請給我留言。

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 中國出海中東和北非地區的策略類手游《蘇丹的復仇》(Revenge of Sultans,ROS)和華為HMS生態深度合作,為本地用戶帶來創新游戲體驗,成為當地廣受歡迎的游戲之一,下載量居應用市場前列。2023年5月10日,在阿聯酋迪拜舉辦的HUAWEI P60系列及旗艦產品發佈會中,ONEMT中東G ...
  • 本文主要介紹在業務複雜化背景下,京東零售購物車團隊努力踐行工匠精神,通過全非同步化改造提升系統性能、提升用戶體驗。通過本文,讀者可以瞭解購物車中台進行全非同步化改造的總體方案,以及方案落地過程中遇到的問題及解決方法,讀者可重點關註文中提到的多分頁並行後,分頁精細控制及底層RPC異常信息問題。 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 avaScript中有些API可能使用率比較低,下麵我們逐一介紹它們的用法和使用場景。 至於標題,主要是想讓你進來看看,兄弟們別打我! Blob API Blob API 用於處理二進位數據,可以方便地將數據轉換為Blob對象或從Blob ...
  • ## n 如果在我的電腦上已經安裝了nodejs,但是覺得這個版本不好用,或者是不相容公司的項目,那麼可以使用n進行node的版本管理。n相對於nvm來說,安裝起來還是非常方便的。 ## 安裝 #### 1. 首先確定nodejs版本,確定已安裝nodejs ``` node -v ``` #### ...
  • Deferred Components,官方實現的Flutter代碼動態下發的方案。本文主要介紹官方方案的實現細節,探索在國內環境下使用Deferred Components,並且實現了最小驗證demo。讀罷本文,你就可以實現Dart文件級別代碼的動態下發。 ...
  • 在 JavaScript 中, undefined 和 null 是兩個特殊的值,用於表示缺失或空值。 undefined 是一個表示未定義或未賦值的原始值。它在以下情況下使用: 1. 變數聲明瞭但未初始化時,預設為 undefined 。 let x; console.log(x); // und ...
  • # React筆記-Hooks(九) ## Hooks ### 概念 >React Hooks 的意思是 組件儘量寫成純函數 如果需要外部功能和副作用 就用鉤子把外部代碼"鉤"進來 ### 函數組件和類組件區別 >- 函數組件沒有狀態(state) 類組件有 >- 函數組件沒有生命周期 類組件有(掛 ...
  • ## 一、模式動機 >觀察者模式用於描述對象之間的依賴關係,它引入了觀察者和觀察目標兩類不同的角色,由於提供了抽象層,它使得增加新的觀察者和觀察目標都很方便。觀察者模式廣泛應用於各種編程語言的事件處理模型中,Java語言也提供了對觀察者模式的全面支持。 - 一個對象的狀態或行為的變化將導致其他對象的 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 在我們開發過程中基本上不可或缺的用到一些敏感機密數據,比如SQL伺服器的連接串或者是OAuth2的Secret等,這些敏感數據在代碼中是不太安全的,我們不應該在源代碼中存儲密碼和其他的敏感數據,一種推薦的方式是通過Asp.Net Core的機密管理器。 機密管理器 在 ASP.NET Core ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 順序棧的介面程式 目錄順序棧的介面程式頭文件創建順序棧入棧出棧利用棧將10進位轉16進位數驗證 頭文件 #include <stdio.h> #include <stdbool.h> #include <stdlib.h> 創建順序棧 // 指的是順序棧中的元素的數據類型,用戶可以根據需要進行修改 ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • C總結與剖析:關鍵字篇 -- <<C語言深度解剖>> 目錄C總結與剖析:關鍵字篇 -- <<C語言深度解剖>>程式的本質:二進位文件變數1.變數:記憶體上的某個位置開闢的空間2.變數的初始化3.為什麼要有變數4.局部變數與全局變數5.變數的大小由類型決定6.任何一個變數,記憶體賦值都是從低地址開始往高地 ...
  • 如果讓你來做一個有狀態流式應用的故障恢復,你會如何來做呢? 單機和多機會遇到什麼不同的問題? Flink Checkpoint 是做什麼用的?原理是什麼? ...
  • C++ 多級繼承 多級繼承是一種面向對象編程(OOP)特性,允許一個類從多個基類繼承屬性和方法。它使代碼更易於組織和維護,並促進代碼重用。 多級繼承的語法 在 C++ 中,使用 : 符號來指定繼承關係。多級繼承的語法如下: class DerivedClass : public BaseClass1 ...
  • 前言 什麼是SpringCloud? Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的開發便利性簡化了分散式系統的開發,比如服務註冊、服務發現、網關、路由、鏈路追蹤等。Spring Cloud 並不是重覆造輪子,而是將市面上開發得比較好的模塊集成進去,進行封裝,從 ...
  • class_template 類模板和函數模板的定義和使用類似,我們已經進行了介紹。有時,有兩個或多個類,其功能是相同的,僅僅是數據類型不同。類模板用於實現類所需數據的類型參數化 template<class NameType, class AgeType> class Person { publi ...
  • 目錄system v IPC簡介共用記憶體需要用到的函數介面shmget函數--獲取對象IDshmat函數--獲得映射空間shmctl函數--釋放資源共用記憶體實現思路註意 system v IPC簡介 消息隊列、共用記憶體和信號量統稱為system v IPC(進程間通信機制),V是羅馬數字5,是UNI ...