日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

一篇文章告訴你真實場景下服務端接口性能問題是如何解決的

來源: 責編: 時間:2024-04-07 17:05:05 166觀看
導讀作為Java后端開發者,我們創作的許多代碼直接影響著用戶的使用體驗。如果后端代碼性能不佳,用戶在訪問網站時就必須花費更多時間等待服務器響應。這可能引發用戶投訴甚至用戶流失問題。性能優化是一個廣泛而重要的話題。

作為Java后端開發者,我們創作的許多代碼直接影響著用戶的使用體驗。如果后端代碼性能不佳,用戶在訪問網站時就必須花費更多時間等待服務器響應。這可能引發用戶投訴甚至用戶流失問題。Zzg28資訊網——每日最新資訊28at.com

性能優化是一個廣泛而重要的話題。《Java程序性能優化》提到性能優化可分為五個層次:設計優化、代碼優化、JVM優化、數據庫優化、操作系統優化等。每個層次都涵蓋許多方法論和最佳實踐。本文無意進行全面詳盡的概述,只是列舉幾個常用的Java代碼優化方案,希望讀者閱讀后能實際應用到自己的代碼中。Zzg28資訊網——每日最新資訊28at.com

單例層面

在處理IO操作、數據庫連接、配置文件解析加載等耗費大量系統資源的任務時,我們必須限制這些實例的創建,或者始終使用一個共享的實例,以節約系統資源。這種情況下就需要使用單例模式。Zzg28資訊網——每日最新資訊28at.com

批量操作

若有100個請求,逐個執行顯然效率較低。將這100個請求合并為一個請求進行批量操作,則能大幅提升效率。Zzg28資訊網——每日最新資訊28at.com

特別是在數據庫操作中,批量處理不僅比逐條執行效率更高,還能有效降低數據庫連接數,提升應用的QPS上限。Zzg28資訊網——每日最新資訊28at.com

Future模式處理

假設某項任務需花費一定時間執行,為避免無謂的等待,可先獲取一個“提貨單”——即Future,隨后繼續處理其他任務,直至“貨物”抵達,即任務執行完成并獲得結果。這時便可憑借“提貨單”提取物品,即通過Future對象獲取返回值。Zzg28資訊網——每日最新資訊28at.com

偽代碼Zzg28資訊網——每日最新資訊28at.com

public class RealData implements Callable<String> {    protected String data;    public RealData(String data) {        this.data = data;    }    @Override    public String call() throws Exception {        // 通過sleep方法演示業務是緩慢的        try {            Thread.sleep(1000);        } catch (InterruptedException e) {            e.printStackTrace();        }        return data;    }}public class Application {    public static void main(String[] args) throws Exception {        FutureTask<String> futureTask =                new FutureTask<>(new RealData("name"));        ExecutorService executor =                Executors.newFixedThreadPool(1); // 使用線程池        // 執行FutureTask,相當于上例中的client.request("name")發送請求        executor.submit(futureTask);        // 這里可以用一個sleep代替對其他業務邏輯的處理        // 在處理這些業務邏輯的同時,RealData也在創建,充分利用等待時間        Thread.sleep(2000);        // 使用真實數據        // 如果call()沒有執行完成,仍會等待        System.out.println("數據=" + futureTask.get());    }}

線程池思路

合理運用線程池帶來三大益處。首先,降低資源消耗:通過重復利用已創建的線程,降低線程的創建與銷毀成本。其次,提高響應速度:任務到達時,無需等待線程創建即可立即執行。第三,提升線程可管理性:線程是珍貴資源,無節制地創建會消耗系統資源,降低系統穩定性;線程池能實現統一分配、優化和監控。Zzg28資訊網——每日最新資訊28at.com

自 Java 5 開始,引入了并發編程新API,如Executor框架,內部采用線程池機制,位于java.util.concurrent包中。通過該框架控制線程的啟動、執行和關閉,可簡化并發編程操作。Zzg28資訊網——每日最新資訊28at.com

偽代碼Zzg28資訊網——每日最新資訊28at.com

public class MultiThreadTest {    public static void main(String[] args) {        ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("thread-%d").build();        ExecutorService executor = new ThreadPoolExecutor(2, 5, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), threadFactory);        executor.execute(new Runnable() {            @Override            public void run() {               System.out.println("Hello, world!");            }        });        System.out.println(" ===> Main Thread! ");    }}

NIO處理

JDK自1.4版本起引入了新的I/O編程類庫,即NIO。NIO不僅帶來了高效的Buffer和Channel,還引入了基于Selector的非阻塞I/O機制,可以將多個異步I/O操作集中到一個或少數幾個線程中進行處理。使用NIO替代阻塞I/O能夠提高程序的并發吞吐能力,降低系統開銷。Zzg28資訊網——每日最新資訊28at.com

針對每個請求,如果為其單獨開啟一個線程來處理邏輯,當客戶端數據傳輸是間歇性的而非連續的時,相應線程會處于I/O等待狀態,并頻繁進行上下文切換。利用NIO引入的Selector機制,可以提升程序的并發效率,改善這種狀況。Zzg28資訊網——每日最新資訊28at.com

偽代碼Zzg28資訊網——每日最新資訊28at.com

public class NioTest {      static public void main( String args[] ) throws Exception {          FileInputStream fin = new FileInputStream("D://test.txt");          // 獲取通道          FileChannel fc = fin.getChannel();          // 創建緩沖區          ByteBuffer buffer = ByteBuffer.allocate(1024);          // 讀取數據到緩沖區          fc.read(buffer);          buffer.flip();          while (buffer.remaining()>0) {              byte b = buffer.get();              System.out.print(((char)b));          }          fin.close();      }  }

優化鎖層面

在并發場景中,頻繁使用鎖是很常見的情況。然而,鎖引發競爭,而競爭又會耗費大量資源。那么,在Java代碼中,如何優化鎖呢?我們可以考慮以下幾個方面:Zzg28資訊網——每日最新資訊28at.com

  • 縮短鎖持有時間
  • 嘗試使用同步代碼塊替代同步方法,從而減少鎖的占用時間。
  • 降低鎖粒度
  • 在并發環境中使用Map時,最好選用ConcurrentHashMap替代HashTable和HashMap(ConcurrentHashMap采用分段鎖,鎖的粒度更細)。Zzg28資訊網——每日最新資訊28at.com

  • 分離鎖Zzg28資訊網——每日最新資訊28at.com

  • 普通鎖(例如synchronized)可能導致讀寫互相阻塞,可以嘗試將讀操作和寫操作分開。Zzg28資訊網——每日最新資訊28at.com

  • 鎖粗化Zzg28資訊網——每日最新資訊28at.com

  • 有時我們希望將多次鎖的請求合并成一個,以減少頻繁加鎖、同步和解鎖所帶來的性能損失。Zzg28資訊網——每日最新資訊28at.com

  • 鎖消除Zzg28資訊網——每日最新資訊28at.com

  • 鎖消除是指Java虛擬機在JIT編譯時,經過運行上下文的掃描,去除那些不會產生共享資源競爭的鎖。通過鎖消除,可以減少無謂的鎖請求時間。Zzg28資訊網——每日最新資訊28at.com

數據傳輸壓縮

在數據傳輸之前,壓縮數據是一種優化方式,可以減少網絡傳輸的數據量,提升傳輸速度。接收端可解壓數據,還原傳輸內容。壓縮后的數據能節省存儲介質(如磁盤或內存)空間和網絡帶寬,從而降低成本。然而,壓縮并非無成本之舉。數據壓縮需要大量CPU計算,并且根據壓縮算法的不同,計算復雜度和壓縮比都有顯著差異。通常需要根據業務情景選擇合適的壓縮算法。Zzg28資訊網——每日最新資訊28at.com

緩存計算結果

對于相同的用戶請求,若每次都重復查詢數據庫、重復計算,將浪費大量時間和資源。將計算結果緩存至本地內存或使用分布式緩存,可節約寶貴的CPU計算資源,減少數據庫重復查詢或磁盤I/O。將原本需要磁頭物理轉動的操作轉化為內存中的電子運動,提高響應速度。同時,快速釋放線程也提升了應用的吞吐能力。Zzg28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-81731-0.html一篇文章告訴你真實場景下服務端接口性能問題是如何解決的

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 京東一面:如何在SpringBoot啟動時執行特定代碼?

下一篇: 詳解WebSocketMessageBrokerConfigurer在SpringBoot中應用與實踐

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 房产| 博乐市| 柘荣县| 南京市| 石狮市| 怀宁县| 兴城市| 盐山县| 铜陵市| 隆林| 仁化县| 天门市| 合作市| 陆川县| 康乐县| 关岭| 铁岭县| 舞阳县| 张家川| 同江市| 南岸区| 息烽县| 博湖县| 灵台县| 鄂温| 拉孜县| 洛南县| 雷波县| 双峰县| 大冶市| 枞阳县| 蒙自县| 桐柏县| 旬邑县| 仁寿县| 吉安县| 怀柔区| 郴州市| 论坛| 班戈县| 通州市|