Q1、SpringBoot可以同時處理多少請求
調試:
寫一個測試接口:
@RestController
@Slf4j
public class RequestController{
@GetMapping("/test")
public String test(HttpServletRequest request) throws Exception{
log.info("線程:{}",Thread.currentThread().getName());
Thread.sleep(2000); //睡兩秒
return "success";
}
}
服務配置中的相關參數(shù):
server:
tomcat:
threads:
# 最少線程數(shù)
min-spare: 10
# 最多線程數(shù)
max: 20
# 最大連接數(shù)
max-connections: 30
# 最大等待數(shù)
accept-count: 10
此時,JMeter模擬100QPS:
成功40個,剛好是(max-connections)+(accept-count)
,而這兩個參數(shù)的默認值可以在Spring-boot-autoconfigure.jar的配置元數(shù)據(jù)的json文件spring-configuration-metadata.json
中找到:(當然也可以直接在application.yaml中按住Ctrl去源碼找)
答案:
max-connections默認值為8192,accept-count默認值100,因此默認情況下,可同時處理8192+100=8292
知識點補充:
1、關于spring-configuration-metadata.json文件
配置spring-configuration-metadata.json文件后,在IDEA中編寫application.yaml等配置文件時,會有提示。
要做一個體驗良好的Starter,這個文件還是非常重要的,對于使用你封裝的開發(fā)者來說,寫配置的時候就會方便很多。關于這個文件的生成,需要引入依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
當再次編譯的時候,??spring-configuration-metadata.json??文件就自動出現(xiàn)了。參考【spring-configuration-metadata.json】
2、關于各參數(shù)含義
首先把web服務器當作是一個飯店:
-
最小工作線程數(shù)
:這個飯店里正式員工的廚師 -
最大工作線程數(shù)
:當客人很多時,正式員工忙不過來,又來了兼職廚師(即最小線程數(shù)下,菜炒不完了) -
最大連接數(shù)
:飯店里最多可容納的客人數(shù)量 -
最大隊列數(shù)
:店里坐不下了,去外面小板凳上坐下排隊的人,即最多可以排隊的人數(shù)。
按照上面調試代碼里的配置,則:正式廚師10個,可招兼職的最多20個,店里能做30人,門口10個小板凳。某一會,來了100個客人,則只能先安排40個,另外60個不會光速走人,會先觀望一下,即有自己的超時時間,等到了超時時間,還沒輪到他進去吃,則走人,msg為connected timeout
。(我上面代碼中執(zhí)行一次休眠2秒,而Jmeter中我設置的timeout時間為200ms,所以表現(xiàn)出來是60個人全部走人了)
Q2、SpringBoot如何優(yōu)化啟動速度
一般在SpringBoot項目啟動中比較耗時的任務比如:數(shù)據(jù)庫建立連接、初始線程池的創(chuàng)建等,可通過延遲這些操作的初始化來優(yōu)化啟動速度。
A1:開啟bean的懶加載
SpringBoot 2.2版本引入spring.main.lazy-initialization
屬性,配置為true,開啟懶加載
,可將所有Bean延遲初始化。
spring:
main:
lazy-initialization: true
A2:創(chuàng)建掃描索引
Spring5之后提供了Spring-context-indexer
功能,通過在編譯時創(chuàng)建一個靜態(tài)候選列表來提高大型應用程序的啟動性能。首先引入依賴:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-indexer</artifactId>
<optional>true</optional>
</dependency>
然后在啟動類上加一個@Indexed
注解,這樣編譯打包時會在項目中生成META-INF/spring.components文件。這個索引文件里,是提前將@ComponentScan需要掃描的bean全部建立好索引并排好順序,然后項目啟動時就根據(jù)這個文件來加載我們所有的Bean
A3:其余思路整理:
- 減少@ComponentScan @SpringBootApplication掃描類時候的范圍
- 關閉 Spring Boot 的JMX監(jiān)控,設置spring.jmx.enabled=false
- 設置JVM參數(shù)-noverify ,不對類進行驗證
- 對非必要啟動時加載的Bean,延遲加載
- 使用SpringBoot的全局懶加載
- AOPQ切面盡量不使用注解方式,這會導致啟動時掃描全部方法
- 關閉endpoint的一些監(jiān)控功能
- 排除項目多余的依賴
- swagger掃描接口時,指定只掃描某個路徑下的類
- Feign客戶端接口的掃描縮小包掃描范圍
A4:還可嘗試一些新特性:
- JDK12后支持G1、JDK13后支持ZGC,可將未使用的內存及時歸還給操作系統(tǒng)
- SpringBoot3的新特性spring-graalvm-native,可將SpringBoot應用程序編譯成本地可執(zhí)行的鏡像文件(顯著優(yōu)化?。?/li>
Q3、談談對Spring的理解
答案:
Spring是一個生態(tài),可以構建java應用所需的一切基礎設施,比如SpringCloud、SpringData、SpringSecurity…通常Spring指的就是Spring Framework。另外:
- Spring是一個輕量級的開源容器框架
- Spring是為了解決企業(yè)級應用開發(fā)的業(yè)務邏輯層和其他各層對象和對象直接的耦合問題
- Spring是一個IOC和AOP的容器框架:IOC控制反轉、面向切面編程AOP、包含并管理應用對象的生命周期的容器
Q4、Spring的優(yōu)缺點
A1:方便解耦,簡化開發(fā)
通過Spring提供的IoC容器,集中管理對象,使得對象和對象之間的耦合度降低,避免硬編碼造成的程序過度耦合,方便維護對象。
A2:AOP的支持:
在不修改原代碼的情況下,對業(yè)務代碼進行增強,減少重復代碼,方便維護。
A3:聲明事務的支持:
使用@Transactional注解進行聲明式的事務管理,不再關注煩悶的事務管理代碼,提高開發(fā)效率。
A4:程序測試方便:
Spring對Junit4的支持,可以通過注解方便的測試Spring程序。
A5:方便集成各種優(yōu)秀框架:
集成能力非常強,只需要做簡單配置就可以集成第三方框架。(Spring底層源碼提供了非常多的可擴展接口)
A6:降低了Java EE中API的使用難度
Spring對Java EE中很多步驟繁瑣的API,如JDBC、JavaMail、遠程調用等提供了封裝
A7:學習的范例
Spring源碼底層的實現(xiàn),比如大量的反射、設計模式、擴展接口等值得學習。但上層使用越簡單,下層封裝和實現(xiàn)就越復雜,想閱讀源碼后做擴展也就不容易了。
Q5、Spring IoC容器是什么?作用與優(yōu)點?
答案:
Ioc,Inversion of Controller,即控制反轉。
UserService service = new UserService();
以上這種寫法耦合度太高,后期發(fā)生修改時維護不方便,引入IoC容器即將創(chuàng)建對象的控制權交給Spring的IoC,在需要某對象的時候直接通過DI(依賴注入)@Autowired自動注入就可以使用對象。簡言之,優(yōu)點就是:
- 集中管理對象,方便維護
- 降低耦合度
Q6、Spring IoC的實現(xiàn)機制是什么
答案:
簡言之是工廠+反射
。以下以基于xml文件為例來說明:
核心代碼:
//反射
return Class.forName("全類名").newInstance();
Spring提供了一個接口BeanFactory。這個接口是Spring實現(xiàn)IOC容器的頂級接口,這個接口是Spring內部使用的,并不是專門為框架的使用者提供的。
我們一般使用的是BeanFactory的子接口ApplicationContext接口,這個接口提供了更多并且更加強大的功能。在ApplicationContext接口中有三個常用的實現(xiàn)類分別是:AnnotationConfigApplicationContext、FileSystemXmlApplicationContext、ClassPathXmlApplicationContext。容器的創(chuàng)建需要讀取配置文件或配置類,通過這些配置告訴Spring哪些bean是需要Spring來進行管理的。
關于這三個類的使用注意點:
Q7、IoC和DI的區(qū)別是什么
答案:
IoC是一種設計的思想和理念,DI是實現(xiàn)IoC重要的一環(huán)。通過DI,IOC可以將依賴項注入到對象中。DI的實現(xiàn)方式主要有:
- 構造方法注入: 被注入的對象可以通過在其構造方法中聲明參數(shù)列表,讓 IoC 容器知道它需要依賴哪些對象
- setter 注入: 為其需要依賴的對象增加 setter 方法,可以通過 setter 方法將其依賴的對象注入到對象中
- 接口注入:基本廢棄
Q8、緊耦合與松耦合的區(qū)別,如何編寫松耦合的代碼
答案:
緊耦合即類和類之間高度依賴,如UserService中來UserMapper userMapper = new UserMapper()。編寫松耦合代碼可以通過以下幾點:
- 單一職責原則
- 接口分離原則
- 依賴倒置原則
早期電腦,很多配件集中在一起,壞掉一個組件,則整個電腦都得扔或者拆開來修。用單一職責原則,則是主機、顯示屏、鍵盤、鼠標分開,如下圖:(對比代碼就是不要所有功能寫一個類里,以及面向過程與面向對象)
僅靠單一職責,不能完全實現(xiàn)松耦合,如早期的鼠標接在主板上,此時連接處發(fā)生故障也不好修,因此再加入接口分離原則:
此時,鼠標故障,拔掉換一個就行,類比代碼中,比如Dao層更換實現(xiàn),或者Service調Dao的方法,Dao更改,不影響Service,但可插拔并不帶表是可熱插拔。不能鼠標一拔,電腦直接不能用了,那再加入依賴倒置原則DIP,而IoC則正好契合了這種原則。文章來源:http://www.zghlxwxcb.cn/news/detail-697771.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-697771.html
到了這里,關于【Spring面試】一、SpringBoot啟動優(yōu)化與最大連接數(shù)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!