鍓嶈█
鍙湁鍏夊ご鎵嶈兘鍙樺己銆�
鏂囨湰宸叉敹褰曡嚦鎴戠殑GitHub绮鹃�夋枃绔狅紝娆㈣繋Star锛�https://github.com/ZhongFuCheng3y/3y
鍥為【涓�涓嬩笂绡囨垜瀵筗ebFlux鐨勫叆闂紝濡傛灉娌¤杩囩殑鍚屽寤鸿璇讳竴涓嬪啀鏉ョ湅鏈瘒鏂囩珷锛屼笂涓�绡囨枃绔犺姳浜嗘垜寰堝鐨勫績琛�~~
- 澶栬浜洪兘鑳界湅鎳傜殑WebFlux锛岄敊杩囦簡琛�浜�
寮�灞�鍐嶆潵涓�寮犲浘锛屽唴瀹瑰叏闈犵紪锛�
杩欑瘒涓昏鍐欏啓鎴戝垵瀛︽椂瀵筗ebFlux鐨勪竴浜涚枒闂紝涓嶇煡閬撳ぇ瀹跺湪鐪嬩笂涓�绡囨枃绔犵殑鏃跺�欐湁娌℃湁鐩稿簲鐨勯棶棰樺憿锛�
杩欐瀛ebFlux涓昏鐨勫姩鍔涙槸鍏徃缁勫唴鍒嗕韩锛屽啓浜嗕竴涓狿PT锛屾湁闇�瑕佺殑鍚屽鍦ㄦ垜鐨勫叕浼楀彿锛�Java3y)涓嬪洖澶嶁�淧PT鈥濆嵆鍙幏鍙栥��
涓�銆佹湰鏉ュ氨鑳藉疄鐜板紓姝ラ潪闃诲锛屼负鍟ヨ鐢╓ebFlux?
鐩镐俊鏈夎繃鐩稿叧浜嗚В鐨勫悓瀛﹂兘鐭ラ亾锛�Servlet 3.1
灏卞凡缁忔敮鎸佸紓姝ラ潪闃诲浜嗐��
鎴戜滑鍙互浠�鑷淮鎶ょ嚎绋嬫睜鐨勬柟寮忓疄鐜板紓姝�
- 璇寸櫧浜嗗氨鏄疶omcat鐨勭嚎绋嬪鐞嗚姹傦紝鐒跺悗鎶婅繖涓姹傚垎鍙戝埌鑷淮鎶ょ殑绾跨▼澶勭悊锛孴omcat鐨勮姹傜嚎绋嬭繑鍥�
@WebServlet(value = "/nonBlockingThreadPoolAsync", asyncSupported = true)
public class NonBlockingAsyncHelloServlet extends HttpServlet {
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(100, 200, 50000L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(100));
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
AsyncContext asyncContext = request.startAsync();
ServletInputStream inputStream = request.getInputStream();
inputStream.setReadListener(new ReadListener() {
@Override
public void onDataAvailable() throws IOException {
}
@Override
public void onAllDataRead() throws IOException {
executor.execute(() -> {
new LongRunningProcess().run();
try {
asyncContext.getResponse().getWriter().write("Hello World!");
} catch (IOException e) {
e.printStackTrace();
}
asyncContext.complete();
});
}
@Override
public void onError(Throwable t) {
asyncContext.complete();
}
});
}
}
娴佺▼鍥惧涓嬶細
涓婇潰鐨勪緥瀛愭潵婧愶細
- https://www.cnblogs.com/davenkin/p/async-servlet.html
绠�鍗曠殑鏂瑰紡锛屾垜浠繕鍙互浣跨敤JDK 8 鎻愪緵鐨�CompletableFuture
绫伙紝杩欎釜绫诲彲浠ユ柟渚跨殑澶勭悊寮傛璋冪敤銆�
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
long t1 = System.currentTimeMillis();
// 寮�鍚紓姝�
AsyncContext asyncContext = request.startAsync();
// 鎵ц涓氬姟浠g爜(doSomething 鎸囩殑鏄鐞嗚�楄垂鏃堕棿闀跨殑鏂规硶)
CompletableFuture.runAsync(() -> doSomeThing(asyncContext,
asyncContext.getRequest(), asyncContext.getResponse()));
System.out.println("async use:" + (System.currentTimeMillis() - t1));
}
瑕佸鐞嗗鏉傜殑閫昏緫鏃讹紝鏃犺鏄洖璋冩垨 CompletableFuture鍦�浠g爜缂栧啓涓婇兘浼氭瘮杈冨鏉�锛堜唬鐮侀噺澶э紝涓嶆槗浜庣湅鎳�)锛岃�學ebFlux浣跨敤鐨勬槸Reactor鍝嶅簲寮忔祦锛岄噷杈�鎻愪緵浜嗕竴绯诲垪鐨凙PI渚涙垜浠幓澶勭悊閫昏緫锛屽氨寰堟柟渚夸簡銆�
鏇撮噸瑕佺殑鏄細
- WebFlux浣跨敤璧锋潵鍙互鍍忎娇鐢⊿pringMVC涓�鏍凤紝鑳藉澶уぇ鍑忓皬瀛︿範鎴愭湰
- WebFlux涔熷彲浠ヤ娇鐢�Functional Endpoints鏂瑰紡缂栫▼锛屾�荤殑鏉ヨ杩樻槸瑕佹瘮
鍥炶皟/CompletableFuture
瑕佺畝娲佸拰鏄撶紪鍐欍��
鍊煎緱涓�鎻愮殑鏄細
濡傛灉Web瀹瑰櫒浣跨敤鐨勬槸Tomcat锛岄偅涔堝氨鏄娇鐢≧eactor妗ユ帴鐨剆ervlet async api
濡傛灉Web瀹瑰櫒鏄疦etty锛岄偅涔堝氨鏄娇鐢ㄧ殑Netty锛屽ぉ鐢熸敮鎸丷eactive瀹樻柟鐨勬帹鑽愭槸浣跨敤Netty璺慦ebFlux
浜屻�乄ebFlux鎬ц兘鐨勯棶棰�
鎴戜滑浠庝笂绡囨枃绔犱腑灏卞彂鐜帮紝娴忚鍣ㄥ幓璋冪敤澶勭悊鎱㈢殑鎺ュ彛锛屾棤璁烘槸璇ユ帴鍙f槸鍚屾鐨勶紝杩樻槸璇存槸寮傛鐨勶紝杩斿洖鍒版祻瑙堝櫒鐨勬椂闂撮兘鏄竴鑷寸殑銆�
- 鍚屾锛氭湇鍔″櫒鎺ユ敹鍒拌姹傦紝涓�涓嚎绋嬩細澶勭悊璇锋眰锛岀洿鍒拌璇锋眰澶勭悊瀹屾垚锛岃繑鍥炵粰娴忚鍣�
- 寮傛锛氭湇鍔″櫒鎺ユ敹鍒拌姹傦紝涓�涓嚎绋嬩細澶勭悊璇锋眰锛岀劧鍚�鎸囨淳鍒殑绾跨▼澶勭悊璇锋眰锛岃姹傜殑绾跨▼鐩存帴绌洪棽鍑烘潵銆�
瀹樼綉涔熻浜嗭細
Reactive and non-blocking generally do not make applications run faster
浣跨敤寮傛闈為樆濉炵殑濂藉灏辨槸锛�
The key expected benefit of reactive and non-blocking is the ability to scale with a small, fixed number of threads and less memory.That makes applications more resilient under load, because they scale in a more predictable way
濂藉锛�鍙渶瑕佸湪绋嬪簭鍐呭惎鍔ㄥ皯閲忕嚎绋嬫墿灞曪紝鑰屼笉鏄按骞抽�氳繃闆嗙兢鎵╁睍銆傚紓姝ヨ兘澶�瑙勯伩鏂囦欢IO/缃戠粶IO闃诲鎵�甯︽潵鐨勭嚎绋嬪爢绉�銆�
涓嬮潰鏉ョ湅涓�涓嬮拡瀵圭浉鍚岀殑璇锋眰閲忥紝鍚屾闃诲鍜屽紓姝ラ潪闃诲鐨勫悶鍚愰噺鍜屽搷搴旀椂闀垮姣旓細
娉細
- 璇锋眰閲忎笉澶ф椂(3000宸﹀彸)锛屽悓姝ラ樆濉炲绾跨▼澶勭悊璇锋眰锛屽悶鍚愰噺鍜屽搷搴旀椂闀块兘娌¤惤鍚庛�傦紙鎸夐亾鐞哤ebFlux鍙兘杩樿钀藉悗涓�浜涳紝姣曠珶澶氬仛浜嗕竴姝ュ鐞�
-->
灏嗚姹傚娲剧粰鍙︿竴涓嚎绋嬪幓鍋氬鐞� - 璇锋眰閲忓ぇ鏃讹紝绾跨▼鏁颁笉澶熺敤锛屽悓姝ラ樆濉�(MVC)鍙兘绛夊緟锛屾墍浠ュ悶鍚愰噺瑕佷笅闄嶏紝鍝嶅簲鏃堕暱瑕佹彁楂�(鎺掗槦)銆�
Spring WebFlux鍦ㄥ簲瀵归珮骞跺彂鐨勮姹傛椂锛屽�熷姪浜庡紓姝O锛岃兘澶熶互灏戦噺鑰岀ǔ瀹氱殑绾跨▼澶勭悊鏇撮珮鍚炲悙閲忕殑璇锋眰锛屽挨鍏舵槸褰撹姹傚鐞嗚繃绋嬪鏋滃洜涓轰笟鍔″鏉傛垨IO闃诲绛夊鑷村鐞嗘椂闀胯緝闀挎椂锛屽姣旀洿鍔犳樉钁椼��
涓夈�乄ebFlux瀹為檯搴旂敤
WebFlux闇�瑕侀潪闃诲鐨勪笟鍔′唬鐮�锛屽鏋滈樆濉烇紝闇�瑕佽嚜宸卞紑绾跨▼姹犲幓杩愯銆俉ebFlux浠�涔堝満鏅笅鍙互鏇挎崲SpringMVC鍛紵
- 鎯宠鍐呭瓨鍜岀嚎绋嬫暟杈冨皯鐨勫満鏅�
- 缃戠粶杈冩參鎴栬�匢O浼氱粡甯稿嚭鐜伴棶棰樼殑鍦烘櫙
SpringMVC鍜學ebFlux鏇村鐨勬槸浜掕ˉ鍏崇郴锛岃�屼笉鏄浛鎹€�傞樆濉炵殑鍦烘櫙璇pringMVC杩樻槸SpringMVC锛屽苟涓嶆槸WebFlux鍑烘潵灏辨妸SpringMVC鍙栦唬浜嗐��
濡傛灉鎯宠鍙戞尌鍑篧ebFlux鐨勬�ц兘锛岄渶瑕佷粠Dao鍒癝ervice锛屽叏閮ㄩ兘瑕佹槸Mono鍜孎lux锛岀洰鍓嶅畼鏂圭殑鏁版嵁灞俁eactive妗嗘灦鍙敮鎸丷edis锛孧ongo绛夊嚑涓紝娌℃湁JDBC銆�
鐩墠瀵逛簬鍏崇郴鍨嬫暟鎹簱锛�Pivotal鍥㈤槦寮�婧愬嚭R2DBC锛圧eactive Relational Database Connectivity锛夛紝鍏禛itHub鍦板潃涓猴細
- https://github.com/r2dbc
鐩墠R2DBC鏀寔涓夌鏁版嵁婧愶細
- PostgreSQL
- H2
- Microsoft SQL Server
鎬荤殑鏉ヨ锛屽洜涓篧ebFlux鏄搷搴斿紡鐨勶紝瑕佹兂鍙戞尌鍑篧ebFlux鐨勬�ц兘灏卞緱灏嗕唬鐮佸叏鏀规垚鍝嶅簲寮忕殑锛岃�孞DBC鐩墠鏄病鏀寔鐨�(鑷冲皯MySQL杩樻病鏀寔)锛岃�屽搷搴斿紡鐨勭▼搴忎笉濂借皟璇曞拰缂栧啓锛堢浉瀵逛簬鍚屾鐨勭▼搴忥級锛屾墍浠ョ幇鍦╓ebFlux鐨勫簲鐢ㄥ満鏅繕鏄浉瀵硅緝灏戠殑銆�
鎵�浠ワ紝鎴戣涓哄湪缃戝叧灞�鐢╓ebFlux姣旇緝鍚堥�傦紙鏈潵灏辨槸缃戠粶IO杈冨鐨勫満鏅級
鐜板湪鍐嶅洖鏉ョ湅Spring瀹樼綉鐨勫浘锛屾槸涓嶆槸灏辨洿浜插垏浜嗭紵
鍙傝�冭祫鏂欙細
- [https://blog.lovezhy.cc/2018/12/29/webflux%E6%80%A7%E8%83%BD%E9%97%AE%E9%A2%98/](https://blog.lovezhy.cc/2018/12/29/webflux鎬ц兘闂/)
鍥涖�佹湁蹇呰瀛unctional Endpoints 缂栫▼妯″紡鍚楋紵
鍓嶉潰涔熸彁鍒颁簡锛學ebFlux鎻愪緵浜嗕袱绉嶆ā寮忎緵鎴戜滑浣跨敤锛屼竴绉嶆槸SpringMVC 娉ㄨВ鐨勶紝涓�绉嶆槸鍙�Functional Endpoints
鐨�
Lambda-based, lightweight, and functional programming model
鎬荤殑鏉ョ湅锛屽氨鏄厤鍚圠ambda鍜屾祦寮忕紪绋嬪幓浣跨敤WebFlux銆傚鏋滀綘闂垜锛氭湁蹇呰瀛﹀悧锛熷叾瀹炴垜瑙夊緱鍙互鍏堟斁鐫�銆�鎴戣涓�鐜板湪WebFlux鐨勫簲鐢ㄥ満鏅繕鏄瘮杈冨皯锛岀瓑鐪熸鐢ㄥ埌鐨勬椂鍊欏啀瀛︿篃涓嶆槸浠�涔堥毦浜嬶紝鍙嶆灏辨槸瀛︿簺API鍢泘
鏈塋ambda琛ㄨ揪寮忓拰Stream娴佺殑鍩虹锛岀瓑鐪熸鐢ㄥ埌鐨勬椂鍊欏啀瀛︿篃涓嶆槸鍟ラ棶棰�~
浠ヤ笅鏄�氳繃娉ㄨВ鐨勬柟寮忔潵浣跨敤WebFlux鐨勭ず渚嬶細
浠ヤ笅鏄�氳繃Functional Endpoints
鐨勬柟寮忔潵浣跨敤WebFlux鐨勭ず渚嬶細
璺敱鍒嗗彂鍣紝鐩稿綋浜庢敞瑙g殑GetMapping...
UserHandler锛岀浉褰撲簬UserController锛�
浜斻�乄ebFlux鐨勫疄闄呬娇鐢ㄥ満鏅�
鎬荤殑鏉ヨ锛屽洜涓篧ebFlux鏄搷搴斿紡鐨勶紝瑕佹兂鍙戞尌鍑篧ebFlux鐨勬�ц兘灏卞緱灏嗕唬鐮佸叏鏀规垚鍝嶅簲寮忕殑锛岃�孞DBC鐩墠鏄病鏀寔鐨�(鑷冲皯MySQL杩樻病鏀寔)锛岃�屽搷搴斿紡鐨勭▼搴忎笉濂借皟璇曞拰缂栧啓锛堢浉瀵逛簬鍚屾鐨勭▼搴忥級锛岃�侀」鐩篃涓嶅お鍙兘鎶婁緷璧栫洿鎺ュ崌涓奡pring5.0锛屾墍浠ョ幇鍦╓ebFlux鐨勫簲鐢ㄥ満鏅繕鏄浉瀵硅緝灏戠殑(涓汉瑙夊緱)銆�
缃戝叧灞傜敤WebFlux姣旇緝鍚堥�傦紙鏈潵灏辨槸缃戠粶IO杈冨鐨勫満鏅級
- SpringCloud Gateway鏄熀浜嶹ebFlux瀹炵幇鐨�
鏈�鍚�
杩欐瀛ebFlux涓昏鐨勫姩鍔涙槸鍏徃缁勫唴鍒嗕韩锛屽啓浜嗕竴涓狿PT锛屾湁闇�瑕佺殑鍚屽鍦ㄦ垜鐨勫叕浼楀彿锛�Java3y)涓嬪洖澶嶁�淧PT鈥濆嵆鍙幏鍙栥��
鏈凡鏀跺綍鑷虫垜鐨凣itHub绮鹃�夋枃绔狅紝娆㈣繋Star锛�https://github.com/ZhongFuCheng3y/3y
涔愪簬杈撳嚭骞茶揣鐨凧ava鎶�鏈叕浼楀彿锛�Java3y銆傚叕浼楀彿鍐�鏈�300澶氱瘒鍘熷垱鎶�鏈枃绔犮�佹捣閲忚棰戣祫婧愩�佺簿缇庤剳鍥撅紝鍏虫敞鍗冲彲鑾峰彇锛�
闈炲父鎰熻阿浜烘墠浠兘鐪嬪埌杩欓噷锛屽鏋滆繖涓枃绔犲啓寰楄繕涓嶉敊锛岃寰椼�屼笁姝�嶆垜鏈夌偣涓滆タ鐨勮瘽 姹傜偣璧� 姹傚叧娉笍 姹傚垎浜煈� 姹傜暀瑷�馃挰 瀵规殩鐢锋垜鏉ヨ鐪熺殑 闈炲父鏈夌敤锛侊紒锛�
鍒涗綔涓嶆槗锛屽悇浣嶇殑鏀寔鍜岃鍙紝灏辨槸鎴戝垱浣滅殑鏈�澶у姩鍔涳紝鎴戜滑涓嬬瘒鏂囩珷瑙侊紒