從客戶端到伺服器再到資料庫的一些思考與疑問

_sanjun發表於2019-04-27
  • 歡迎大家提出自己的疑問點
  • 本人在web應用開發的學習過程中,以Java語言為主線,在使用者訪問伺服器的過程中,涉及到的一些細節問題,所以作此文,希望大家能夠指點一二。

Web應用架構圖

從客戶端到伺服器再到資料庫的一些思考與疑問

焦點

  • 本文圍繞HTTP連線,併發處理(Java執行緒池),資料庫連線池三方面進行逐一思考和解決,是一個學習的過程,希望得到大家的解答
重點疑問
  • 主要是思考我們平時學習的Java併發,為什麼在平時開發web應用時,完全沒有去使用?
  • 是不是Spring體系框架已經內部處理這種併發訪問的連線?
  • 那我們平時學習這些建立執行緒,執行緒池的作用在哪裡?為了面試?
  • 一般我們都是使用main方法來啟動多執行緒,學習多執行緒,但是我們有沒有思考過,大量的訪問到來時,需要我們去寫併發來處理這些訪問?我們是如何讓每個執行緒自動去接收這些請求並處理的 ?
  • 這些都是我的疑問,也是寫這個文章的原因,但願大家能夠分享自己的見解
  • 如果沒能夠理解我的問題,可以留言,我會一一完善。

客戶端

  • 1、首先我們經常在網上看到一些文章,類似名為《從瀏覽器輸入url到頁面的顯示的全過程》,文章能夠為了闡述整個思路
  • 2、我們在瀏覽器上輸入url後,會進行DNS解析,再根據IP進行訪問。當有大量的使用者同時訪問同一個站點時,根據HTTP各版本的型別,針對HTTP連線有不同的進化(HTTP1.0預設使用短連線,HTTP使用長連線)
  • 3、長連線,當一個網頁開啟後,客戶端和服務端之間的連線不會關閉,保持一個設定的時間,客戶端再次訪問這個伺服器時,會繼續使用這個連線。

伺服器端

Spring框架內建執行緒池
  • 毋庸置疑,平時我們寫web應用網站時,都是因為我們使用了框架,所以才會感覺到一直在寫業務邏輯程式碼,學習過的併發從未派上過用場,這是因為框架使併發透明化,“摸不著,看不見”。
  • 對於Spring的系統,一般都分為Controller,Service,DAO;對於Service,一般會注入DAO,而DAO就回用到資料連線Connection,我們知道Connection是有狀態的,在多執行緒環境下,肯定會遇到問題,Spring為我們考慮到了這種情況,對此做了特殊處理,只要使用Spring提供的執行緒繫結資源獲取工具得到的Connection就是執行緒安全的,JDBC或MyBatis對應DataSourceUtils,Hibernate對應SessionFactoryUtils,從相應的工具類中獲取的Connection,通過了ThreadLocal處理,所以不會出現執行緒安全問題。另外Spring為我們做了更多事情,我們可以不必自己取獲取Connection,Spring為我們提供了DAO模板類,JDBC對應JdbcTemplate,Hibernate對應HibernateTemplate,MyBatis對應SqlMapClientTemplate,直接使用模板進行資料訪問操作完全不用擔心執行緒安全問題(其內部其實也是呼叫了相應的工具類)。所以我們的DAO完全可以成為singletion 物件。然後只要使用Spring提供的事務管理,我們的Service也同樣可以成為singletion 物件。而我們的Controller,如果只注入了Service,而沒有其他狀態物件,同樣可以成為singletion 物件。當然了,如果還包含其他有狀態的成員屬性,Spring也是無能為力的,這時候只能定義為request或者其他合適的物件了。(摘抄https://www.oschina.net/question/661185_116863)
  • 配置執行緒池
<!-- spring thread pool executor -->           
    <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <!-- 執行緒池維護執行緒的最少數量 -->
        <property name="corePoolSize" value="5" />
        <!-- 允許的空閒時間 -->
        <property name="keepAliveSeconds" value="200" />
        <!-- 執行緒池維護執行緒的最大數量 -->
        <property name="maxPoolSize" value="10" />
        <!-- 快取佇列 -->
        <property name="queueCapacity" value="20" />
        <!-- 對拒絕task的處理策略 -->
        <property name="rejectedExecutionHandler">
            <bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" />
        </property>
    </bean>
複製程式碼
自己搭建一個處理併發訪問的框架??
  • 線索1:我們平時接觸的tomcat,套接字Socket就是專門接收客戶端請求的,可否從這入手理解?
  • 線索2:利用多執行緒來實現一個簡單的伺服器,來實現處理多個使用者的請求??
  • 線索3:多執行緒+Socket實現多使用者多功能並行請求的服務端設計

資料庫

  • 資料庫連線池druid
  • 連線這類知識,無非就是建立和銷燬會消耗大量資源,保持個別連線存活,不但節省資源,而且還能夠提高效能

總結

  • 這篇文章也許沒什麼乾貨,但它讓我的思考找到了一些解決的思路
    1. 自己動手去實現一個簡單的多執行緒處理多個使用者請求的伺服器
    1. 不斷探索tomcat的原理,它是其他框架,如SpringMVC的鼻祖
    1. 多思考web應用的整個流程,只有打通各個環節,架起一座大廈的框架,其餘的事就是不斷地搬磚添瓦。

相關文章