開源框架知識
- 簡單講講tomcat結構,以及其類加載器流程,線程模型等。
-
Tomcat結構
-
tomcat的conf目錄下的server.xml 配置文件可體現Tomcat結構。Tomcat中只有一個server,一個server可以有多個service,一個service可以有多個Connector和一個Container
-
service 是對外提供服務的。Connector用於接收請求並將請求封裝成Request和Response.
Container用於封裝和管理servlet,以及處理request請求
-
一個請求發送到Tomcat之後,首先經過Service然後會交給我們的Connector,Connector用於接收請求並將接收的請求封裝爲Request和Response來具體處理,Request和Response封裝完之後再交由Container進行處理,Container處理完請求之後再返回給Connector,最後在由Connector通過Socket將處理的結果返回給客戶端
-
-
類加載流程
- BootStrap啓動類加載—> System 系統類加載------> Common 通用類加載-----> Webapp 通用類加載
-
線程模型
-
BIO:阻塞式IO,採用傳統的java IO進行操作,該模式下每個請求都會創建一個線程,
適用於併發量小的場景
-
NIO:同步非阻塞,比傳統BIO能更好的支持大併發,tomcat 8.0 後默認採用該模式
-
APR:tomcat 以JNI形式調用http服務器的核心動態鏈接庫來處理文件讀取或網絡傳輸操作,需要編譯安裝APR庫
-
AIO:異步非阻塞,tomcat8.0後支持
-
- tomcat如何調優,涉及哪些參數 。
- JVM參數調優
- -server : 使tomcat以server模式運行,這個模式下將擁有:更大、更高的併發處理能力,更快更強捷的JVM垃圾回收機 制,可以有更大的負載與吞吐量
- -Xms -Xmx: jvm 堆設置
- -Xss 堆棧設置
- -XX:PermSize 和 -XX:MaxPermSize:非堆設置
- Tomcat配置優化
- connectionTimeout: 超時時間單位是ms,併發要求高的話,將此值減少!
- acceptCount: 當指定的連接數被用盡時,可放到出列隊列中的數量,也即可接受的排隊數量.
- maxThreads: Tomcat可創建的最大的線程數(每一個線程對應一個請求), maxThreads決定了tomcat的最大線程閥值,需要設置的大一些
- maxKeepAliveRequests: 表示該連接最大支持的請求次數。
- 講講Spring加載流程。
- 創建ServletContext --> 觸發容器初始化cotextInitialized->創建上下文WebApplicationContext
- spring bean 生命週期
- 實例化 Instantiation --> 屬性賦值 Populate --> 初始化 Initialization -->銷燬 Destruction
- 屬性賦值後調用spring接口實現獲取額外信息:BeanNameAware、BeanFactoryAware、ApplicationContextAware、EnvironmentAware 等等獲取spring容器內的資源信息。
- BeanPostProcessor 接口實現類加載在 實例化 和 初始化 階段 用來影響bean對象,添加自定義邏輯。
- Spring AOP的實現原理。
- spring aop通過代理模式生成代理對象,在不修改源代碼情況下,對實現功能進行增強。其提供兩種動態代理方式:
- jdk動態代理
- cglib動態代理
- aop有多個場景應用:日誌、事務、懶加載、緩存、權限
- 講講Spring事務的傳播屬性。
- PROPAGATION_REQUIRED:支持當前事務,如果當前沒有事務,就新建一個事務。這是最常見的選擇,也是 Spring 默認的事務的傳播。
- PROPAGATION_REQUIRES_NEW:新建事務,如果當前存在事務,把當前事務掛起
- PROPAGATION_SUPPORTS:支持當前事務,如果當前沒有事務,就以非事務方式執行。
- PROPAGATION_MANDATORY:支持當前事務,如果當前沒有事務,就拋出異常。
- PROPAGATION_NOT_SUPPORTED:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。
- PROPAGATION_NEVER:以非事務方式執行,如果當前存在事務,則拋出異常。
- PROPAGATION_NESTED:如果一個活動的事務存在,則運行在一個嵌套的事務中。
- Spring如何管理事務的。
- spring最初會去連接池中獲取一個數據庫連接,獲取到連接之後修改數據庫提價方式爲手動提交,然後配合spring動態代理對象完成。
- spring事務管理主要由三個接口配合完成
- PlatformTransactionManager:事務管理器–主要用於平臺相關事務的管理
- TransactionDefinition:事務定義信息–用來定義事務相關的屬性,給事務管理器PlatformTransactionManager使用
- TransactionStatus:事務具體運行狀態–事務管理過程中,每個時間點事務的狀態信息。
- spring循環注入的原理
- 循環注入三種情形
- 構造器注入。觸發循環依賴,拋出BeanCurrentlyInCreationException異常
- 單例bean的setter注入; Spring是先將Bean對象實例化之後,再設置對象屬性,所以會先調用他的無參構造函數實例化。每個對象存在一個map中。當遇到依賴,就去map中調用對應的單例對象。
- 多例bean的setter注入;對於“prototype”作用域Bean,Spring容器無法完成依賴注入,因爲“prototype”作用域的Bean,Spring容器不進行緩存,因此無法提前暴露一個創建中的Bean。
-
Springmvc 中DispatcherServlet初始化過程。
- 用戶發送請求至前端控制器DispatcherServlet。
- DispatcherServlet收到請求調用HandlerMapping處理器映射器。
- 處理器映射器找到具體的處理器(可以根據xml配置、註解進行查找),生成處理器對象及處理器攔截器(如果有則生成)一併返回給DispatcherServlet。
- DispatcherServlet調用HandlerAdapter處理器適配器。
- HandlerAdapter經過適配調用具體的處理器(Controller,也叫後端控制器)。
- Controller執行完成返回ModelAndView。
- HandlerAdapter將controller執行結果ModelAndView返回給DispatcherServlet。
- DispatcherServlet將ModelAndView傳給ViewReslover視圖解析器。
- ViewReslover解析後返回具體View.
- DispatcherServlet根據View進行渲染視圖(即將模型數據填充至視圖中)。
- DispatcherServlet響應用戶。
-
springmvc用到的註解,作用是什麼,原理。
- controller、service、repository、component 這四個註解分別作用域控制層、業務層、持久層,第四個常用配置類。當spring容器進行加載的時候,會將標記爲以上註解的類注入到spring容器中。
- @Autowired 自動裝配,默認是類型匹配。當有需要名稱匹配時可搭配@Qualifier(“class-name”)註解
- @Resource註解,默認通過name屬性去匹配bean,當找不到時再按type去匹配,當指定了name或者type則根據指定的類型去匹配bean
- component-scan標籤默認情況下自動掃描指定路徑下的包
- RequestMapping是一個用來處理請求地址映射的註解,可用於類或方法上
- springboot啓動機制。
- @SpringBootApplication : springboot啓動註解,負責掃描註冊全局,是springboot的核心註解,它其實是一個組合註解
- @SpringBootConfiguration: 內部引用@Configuration,用於標識這個類可以使用Spring IoC容器作爲bean定義的來源。其搭配註解@Bean註解告訴Spring,一個帶有@Bean的註解方法將返回一個對象,該對象應該被註冊爲在Spring應用程序上下文中的bean。
- @ComponentScan:自動掃描並加載符合條件的組件(比如@Component和@Repository等)或者bean定義,最終將這些bean定義加載到IoC容器中。
- @EnableAutoConfiguration:藉助@Import的支持,收集和註冊特定場景的相關bean定義,將所有符合自動配置條件的bean定義加載到IoC容器
- EnableAutoConfigurationImportSelector:@Import(EnableAutoConfigurationImportSelector.class)
- SpringFactoriesLoader:其主要功能就是從指定的配置文件META-INF/spring.factories加載配置。
- SpringApplication的run方法:開始->收集條件->準備環境->創建並實例ApplicationContext->refresh->結束
- 創建一個SpringApplication對象實例,並通知創建應用開始。
- 創建並配置當前Spring Boot應用將要使用的Environment,並通知環境配置已經加載
- ApplicationContext創建
- 將之前通過@EnableAutoConfiguration獲取的配置加載到ApplicationContext
- ApplicationContext的refresh()
- netty的線程模型,netty如何基於reactor模型上實現的。
- Reactor 單線程模式:是指所有的 I/O 操作都在同一個 NIO 線程上面完成的,此時NIO線程職責包括:接收新建連接請求、讀寫操作等。
- Rector 多線程模型:與單線程模型最大的區別就是有一組 NIO 線程來處理連接讀寫操作,一個NIO線程處理Accept。一個NIO線程可以處理多個連接事件,一個連接的事件只能屬於一個NIO線程。
- 主從 Reactor 線程模型:服務端用於接收客戶端連接的不再是一個單獨的 NIO 線程,而是一個獨立的 NIO 線程池。
- netty 的線程模型並不是一成不變的,它實際取決於用戶的啓動參數配置。通過設置不同的啓動參數,Netty 可以同時支持 Reactor 單線程模型、多線程模型。
- 爲什麼選擇netty。
- Netty是一個高性能、異步事件驅動的NIO框架,它提供了對TCP、UDP和文件傳輸的支持,作爲一個異步NIO框架,Netty的所有IO操作都是異步非阻塞的,通過Future-Listener機制,用戶可以方便的主動獲取或者通過通知機制獲得IO操作結果。
- netty的fashwheeltimer的用法,實現原理,是否出現過調用不夠準時,怎麼解決
- HashedWheelTimer提供的是一個定時任務的一個優化實現方案,在netty中主要用於異步IO的定時規劃觸發
- netty的心跳處理在弱網下怎麼辦。
- 所謂心跳, 即在 TCP 長連接中, 客戶端和服務器之間定期發送的一種特殊的數據包, 通知對方自己還在線, 以確保 TCP 連接的有效性.一個連接如果長時間不用,防火牆或者路由器就會斷開該連接。對於如何監測連接是否斷開,則是通過重寫ChannelInboundHandler#channelInactive來實現,但連接不可用,該方法會被觸發
- 什麼是TCP粘包,拆包。解決方式是什麼。
- 粘包:假設客戶端向服務端連續發送了兩個數據包,接收端只收到一個數據包,由於TCP是不會出現丟包的,所以這一個數據包中包含了發送端發送的兩個數據包的信息,這種現象即爲粘包
- 拆包:接收端收到了兩個數據包,但是這兩個數據包要麼是不完整的,要麼就是多出來一塊,這種情況即發生了拆包和粘包
- 原因:
- 要發送的數據大於TCP發送緩衝區剩餘空間大小,將會發生拆包。
- 待發送數據大於MSS(最大報文長度),TCP在傳輸前將進行拆包。
- 要發送的數據小於TCP發送緩衝區的大小,TCP將多次寫入緩衝區的數據一次發送出去,將會發生粘包
- 接收數據端的應用層沒有及時讀取接收緩衝區中的數據,將發生粘包。
- 解決辦法:
- 發送端給每個數據包添加包首部,首部中應該至少包含數據包的長度,這樣接收端在接收到數據後,通過讀取包首部的長度字段,便知道每一個數據包的實際長度了。
- 發送端將每個數據包封裝爲固定長度(不夠的可以通過補0填充),這樣接收端每次從接收緩衝區中讀取固定長度的數據就自然而然的把每個數據包拆分開來。
- 可以在數據包之間設置邊界,如添加特殊符號,這樣,接收端通過這個邊界就可以將不同的數據包拆分開。