微服務-微服務API網關Spring-clould-gateway實戰

1. 需求背景

????????在微服務架構中,通常一個系統會被拆分為多個微服務,面對這么多微服務客戶端應該如何去調用呢?
如果根據每個微服務的地址發起調用,存在如下問題:
? ? ? ? 1.客戶端多次請求不同的微服務,會增加客戶端代碼和配置的復雜性,維護成本比價高
? ? ? ? 2.認證復雜,每個微服務可能存在不同的認證方式,客戶端去調用,要去適配不同的認證
? ? ? ? 3.存在跨域的請求,調用鏈有一定的相對復雜性(防火墻 / 瀏覽器不友好的協議)
? ? ? ? 4.難以重構,隨著項目的迭代,可能需要重新劃分微服務
為了解決上面的問題,微服務引入了 API 網關 的概念, API 網關為微服務架構的系統提供簡單、有效且 統一的 API 路由管理,作為系統的統一入口 ,提供內部服務的路由中轉,給客戶端提供統一的服務,可 以實現一些和業務沒有耦合的公用邏輯,主要功能包含認證、鑒權、路由轉發、安全策略、防刷、流 量控制、監控日志等。

2. 什么是Spring Cloud Gateway

????????Spring Cloud Gateway 是Spring Cloud官方推出的第二代網關框架,定位于取代 Netflix Zuul。Spring Cloud Gateway 旨在為微服務架構提供一種簡單且有效的 API 路由的管理方式,并基于 Filter 的方式提供網關的基本功能,例如說安全認證、監控、限流等等。

????????Spring Cloud Gateway 是由 WebFlux + Netty + Reactor 實現的響應式的 API 網關。它不能在傳統的 servlet 容器中工作,也不能構建成 war 包。

官網文檔:Spring Cloud Gateway

1.2 核心概念

  • 路由(route)

路由是網關中最基礎的部分,路由信息包括一個ID、一個目的URI、一組斷言工廠、一組Filter組成。

  • 斷言(predicates)

Java8中的斷言函數,SpringCloud Gateway中的斷言函數類型是Spring5.0框架中的ServerWebExchange。斷言函數允許開發者去定義匹配Http request中的任何信息,比如請求頭和參數等。如果斷言為真,則說明請求的URL和配置的路由匹配。

  • 過濾器(Filter)

SpringCloud Gateway中的filter分為Gateway FilIer和Global Filter。Filter可以對請求和響應進行處理。

1.2 工作原理

????????Spring Cloud Gateway 的工作原理跟 Zuul 的差不多,最大的區別就是 Gateway 的 Filter 只有 pre 和 post 兩種。

客戶端向 Spring Cloud Gateway 發出請求,如果請求與網關程序定義的路由匹配,則該請求就會被發送到網關 Web 處理程序,此時處理程序運行特定的請求過濾器鏈。

過濾器之間用虛線分開的原因是過濾器可能會在發送代理請求的前后執行邏輯。所有 pre 過濾器邏輯先執行,然后執行代理請求;代理請求完成后,執行 post 過濾器邏輯。

3. Spring Cloud Gateway實戰

3.1 微服務快速接入Spring Cloud Gateway

1) 引入依賴
<!-- gateway網關 -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId>
</dependency><!-- nacos服務注冊與發現 -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>

注意:gateway會和spring-webmvc的依賴沖突,需要排除spring-webmvc

2) 編寫yml配置文件
spring:application:name: mall-gateway#配置nacos注冊中心地址cloud:nacos:discovery:server-addr: 127.0.0.1:8848gateway:#設置路由:路由id、路由到微服務的uri、斷言routes:- id: order_route  #路由ID,全局唯一,建議配置服務名uri: lb://mall-order  #lb 整合負載均衡器loadbalancerpredicates:- Path=/order/**   # 斷言,路徑相匹配的進行路由- id: user_route   #路由ID,全局唯一,建議配置服務名uri: lb://mall-user  #lb 整合負載均衡器loadbalancerpredicates:- Path=/user/**   # 斷言,路徑相匹配的進行路由
3)測試

http://localhost:8888/order/findOrderByUserId/1

3.2 路由斷言工廠(Route Predicate Factories)配置

predicates:路由斷言,判斷請求是否符合要求,符合則轉發到路由目的地。application.yml配置文件中寫的斷言規則只是字符串,這些字符串會被Predicate Factory讀取并處理,轉變為路由判斷的條件

文檔:Spring Cloud Gateway

通過網關啟動日志,可以查看內置路由斷言工廠:

3.2.1 路徑匹配
spring:cloud:gateway:#設置路由:路由id、路由到微服務的uri、斷言routes:- id: order_route  #路由ID,全局唯一uri: lb://mall-order  #目標微服務的請求地址和端口predicates:# 測試:http://localhost:8888/order/findOrderByUserId/1- Path=/order/**    # 斷言,路徑相匹配的進行路由
3.2.2 Header匹配
spring:cloud:gateway:#設置路由:路由id、路由到微服務的uri、斷言routes:- id: order_route  #路由ID,全局唯一uri: lb://mall-order  #目標微服務的請求地址和端口predicates:- Path=/order/**   # 斷言,路徑相匹配的進行路由# Header匹配  請求中帶有請求頭名為 x-request-id,其值與 \d+ 正則表達式匹配- Header=X-Request-Id, \d+

測試

3.3 過濾器工廠(?GatewayFilter?Factories)配置

GatewayFilter是網關中提供的一種過濾器,可以對進入網關的請求和微服務返回的響應做處理

Spring Cloud Gateway

3.3.1 添加請求頭

需求:給所有進入mall-order的請求添加一個請求頭:X-Request-color=red。

只需要修改gateway服務的application.yml文件,添加路由過濾即可:

spring:cloud:gateway:#設置路由:路由id、路由到微服務的uri、斷言routes:- id: order_route  #路由ID,全局唯一uri: http://localhost:8020  #目標微服務的請求地址和端口#配置過濾器工廠filters:- AddRequestHeader=X-Request-color, red  #添加請求頭

測試http://localhost:8888/order/testgateway

@GetMapping("/testgateway")
public String testGateway(HttpServletRequest request) throws Exception {log.info("gateWay獲取請求頭X-Request-color:"+request.getHeader("X-Request-color"));return "success";
}
@GetMapping("/testgateway2")
public String testGateway(@RequestHeader("X-Request-color") String color) throws Exception {log.info("gateWay獲取請求頭X-Request-color:"+color);return "success";
}

3.3.2 添加請求參數
spring:cloud:gateway:#設置路由:路由id、路由到微服務的uri、斷言routes:- id: order_route  #路由ID,全局唯一uri: http://localhost:8020  #目標微服務的請求地址和端口#配置過濾器工廠filters:- AddRequestParameter=color, blue  # 添加請求參數

測試http://localhost:8888/order/testgateway3

@GetMapping("/testgateway3")
public String testGateway3(@RequestParam("color") String color) throws Exception {log.info("gateWay獲取請求參數color:"+color);return "success";
}

3.3.3 自定義過濾器工廠

繼承AbstractNameValueGatewayFilterFactory且我們的自定義名稱必須要以GatewayFilterFactory結尾并交給spring管理。

@Component
@Slf4j
public class CheckAuthGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {@Overridepublic GatewayFilter apply(NameValueConfig config) {return (exchange, chain) -> {log.info("調用CheckAuthGatewayFilterFactory==="+ config.getName() + ":" + config.getValue());return chain.filter(exchange);};}
}

配置自定義的過濾器工廠

spring:cloud:gateway:#設置路由:路由id、路由到微服務的uri、斷言routes:- id: order_route  #路由ID,全局唯一uri: http://localhost:8020  #目標微服務的請求地址和端口#配置過濾器工廠filters:- CheckAuth=fox,男   #自定義過濾器工廠

測試

3.4 全局過濾器(Global Filters)配置

全局過濾器的作用也是處理一切進入網關的請求和微服務響應,與GatewayFilter的作用一樣。

  • GatewayFilter:網關過濾器,需要通過spring.cloud.routes.filters配置在具體的路由下,只作用在當前特定路由上,也可以通過配置spring.cloud.default-filters讓它作用于全局路由上。
  • GlobalFilter:全局過濾器,不需要再配置文件中配置,作用在所有的路由上,最終通過GatewayFilterAdapter包裝成GatewayFilterChain能夠識別的過濾器。

Spring Cloud Gateway

3.4.1 ReactiveLoadBalancerClientFilter

ReactiveLoadBalancerClientFilter 會查看exchange的屬性ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR的值(一個URI,比如lb://mall-order/order/testgateway2?color=blue),如果該值的scheme是 lb,比如:lb://myservice ,它將會使用Spring Cloud的LoadBalancerClient 來將 myservice 解析成實際的host和port。

其實就是用來整合負載均衡器loadbalancer的

spring:cloud:gateway:routes:- id: order_routeuri: lb://mall-orderpredicates:- Path=/order/**
3.4.2 自定義全局過濾器

自定義全局過濾器定義方式是實現GlobalFilter接口。每一個過濾器都必須指定一個int類型的order值,order值越小,過濾器優先級越高,執行順序越靠前。GlobalFilter通過實現Ordered接口來指定order值

@Component
@Slf4j
public class CheckAuthFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {//獲取tokenString token = exchange.getRequest().getHeaders().getFirst("token");if (null == token) {log.info("token is null");ServerHttpResponse response = exchange.getResponse();response.getHeaders().add("Content-Type","application/json;charset=UTF-8");// 401 用戶沒有訪問權限response.setStatusCode(HttpStatus.UNAUTHORIZED);byte[] bytes = HttpStatus.UNAUTHORIZED.getReasonPhrase().getBytes();DataBuffer buffer = response.bufferFactory().wrap(bytes);// 請求結束,不繼續向下請求return response.writeWith(Mono.just(buffer));}//TODO 校驗token進行身份認證log.info("校驗token");return chain.filter(exchange);}@Overridepublic int getOrder() {return 2;}
}

3.5 Gateway跨域資源共享配置(CORS Configuration)

在前端領域中,跨域是指瀏覽器允許向服務器發送跨域請求,從而克服Ajax只能同源使用的限制。

同源策略(Same Orgin Policy)是一種約定,它是瀏覽器核心也最基本的安全功能,它會阻止一個域的js腳本和另外一個域的內容進行交互,如果缺少了同源策略,瀏覽器很容易受到XSS、CSRF等攻擊。所謂同源(即在同一個域)就是兩個頁面具有相同的協議(protocol)、主機(host)和端口號(port)。

CORS: 跨源資源共享(CORS) - HTTP | MDN

測試代碼:

測試結果

如何解決gateway跨域問題?

通過yml配置的方式

Spring Cloud Gateway

spring:cloud:gateway:globalcors:cors-configurations:'[/**]':allowedOrigins: "*"allowedMethods:- GET- POST- DELETE- PUT- OPTION
通過 java 配置的方式
 @Configurationpublic class CorsConfig {@Beanpublic CorsWebFilter corsFilter() {CorsConfiguration config = new CorsConfiguration();config.addAllowedMethod("*");config.addAllowedOrigin("*");config.addAllowedHeader("*");UrlBasedCorsConfigurationSource source = new
UrlBasedCorsConfigurationSource(new PathPatternParser());source.registerCorsConfiguration("/**", config);return new CorsWebFilter(source);}}

3.6 Gateway基于redis+lua腳本限流

spring cloud 官方提供了 RequestRateLimiter 過濾器工廠,基于 redis+lua 腳本方式采用令牌桶算法實現了限流。
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#the-requestratelimiter-gatewayfilter-factory
請求不被允許時返回狀態: HTTP 429 - Too Many Requests

?

?1)添加依賴
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis-reactive</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId>
</dependency>
2)修改 application.yml ,添加redis配置和RequestRateLimiter過濾器工廠配置
spring:application:name: mall-gatewaydata:#配置redis地址redis:host: localhostport: 6379database: 0timeout: 5000lettuce:pool:max-active: 200max-wait: 10000max-idle: 100min-idle: 10#配置nacos注冊中心地址cloud:nacos:discovery:server-addr: 127.0.0.1:8848gateway:#設置路由:路由id、路由到微服務的uri、斷言routes:- id: order_route  #路由ID,全局唯一,建議配置服務名# 測試 http://localhost:8888/order/findOrderByUserId/1uri: lb://mall-order  #lb 整合負載均衡器ribbon,loadbalancerpredicates:- Path=/order/**   # 斷言,路徑相匹配的進行路由#配置過濾器工廠filters:- name: RequestRateLimiter   #限流過濾器args:redis-rate-limiter.replenishRate: 1 #令牌桶每秒填充速率redis-rate-limiter.burstCapacity: 2 #令牌桶的總容量key-resolver: "#{@keyResolver}" #使用SpEL表達式,從Spring容器中獲取Bean對象
3) 配置keyResolver,可以指定限流策略,比如url限流,參數限流,ip限流等等
@Bean
KeyResolver keyResolver() {//url限流return exchange -> Mono.just(exchange.getRequest().getURI().getPath());//參數限流//return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}
4) 測試

url限流:http://localhost:8888/order/findOrderByUserId/1

參數限流:http://localhost:8888/order/findOrderByUserId/1?user=fox

3.7 Gateway整合sentinel限流

從 1.6.0 版本開始,Sentinel 提供了 Spring Cloud Gateway 的適配模塊,可以提供兩種資源維度的限流:

  • route 維度:即在 Spring 配置文件中配置的路由條目,資源名為對應的 routeId
  • 自定義 API 維度:用戶可以利用 Sentinel 提供的 API 來自定義一些 API 分組

sentinel網關流控:api-gateway-flow-control | Sentinel

3.7.1 Gateway整合sentinel實現網關限流
1)引入依賴
<!-- gateway接入sentinel  -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2)添加yml配置,接入sentinel dashboard,通過sentinel控制臺配置網關流控規則
server:port: 8888
spring:application:name: mall-gateway-sentinel-demomain:allow-bean-definition-overriding: true#配置nacos注冊中心地址cloud:nacos:discovery:server-addr: 127.0.0.1:8848sentinel:transport:# 添加sentinel的控制臺地址dashboard: 127.0.0.1:8080gateway:#設置路由:路由id、路由到微服務的uri、斷言routes:- id: order_route  #路由ID,全局唯一,建議配合服務名uri: lb://mall-order  #lb 整合負載均衡器loadbalancerpredicates:- Path=/order/**- id: user_routeuri: lb://mall-user  #lb 整合負載均衡器loadbalancerpredicates:- Path=/user/**

注意:基于SpringBoot3的 Spring Cloud Gateway和Sentinel還存在兼容性問題,等待Sentinel官方對最新的Gateway適配包更新

3.7.2 Sentinel網關流控實現原理

????????當通過?GatewayRuleManager?加載網關流控規則(GatewayFlowRule)時,無論是否針對請求屬性進行限流,Sentinel 底層都會將網關流控規則轉化為熱點參數規則(ParamFlowRule),存儲在?GatewayRuleManager?中,與正常的熱點參數規則相隔離。轉換時 Sentinel 會根據請求屬性配置,為網關流控規則設置參數索引(idx),并同步到生成的熱點參數規則中。

????????外部請求進入 API Gateway 時會經過 Sentinel 實現的 filter,其中會依次進行?路由/API 分組匹配、請求屬性解析和參數組裝。Sentinel 會根據配置的網關流控規則來解析請求屬性,并依照參數索引順序組裝參數數組,最終傳入?SphU.entry(res, args)?中。Sentinel API Gateway Adapter Common 模塊向 Slot Chain 中添加了一個?GatewayFlowSlot,專門用來做網關規則的檢查。GatewayFlowSlot?會從?GatewayRuleManager?中提取生成的熱點參數規則,根據傳入的參數依次進行規則檢查。若某條規則不針對請求屬性,則會在參數最后一個位置置入預設的常量,達到普通流控的效果。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/697677.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/697677.shtml
英文地址,請注明出處:http://en.pswp.cn/news/697677.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Qt 事件

1. 事件 事件是對各種應用程序需要知道的由應用程序內部或者外部產生的事情或者動作的通稱。在Qt中使用一個對象來表示一個事件&#xff0c;它繼承自QEvent類。 2. 事件和信號 事件與信號并不相同&#xff0c;比如我們使用鼠標點擊了一下界面上的按鈕&#xff0c;那么就會產生…

node 之 初步認識

思考&#xff1a;為什么JavaScript可以在瀏覽器中被執行 代執行的js代碼——JavaScript解析引擎 不同的瀏覽器使用不同的JavaScript解析引擎 Chrome 瀏覽器 》 V8 Firefox瀏覽器 》OdinMonkey(奧丁猴&#xff09; Safri瀏覽器 》JSCore IE瀏覽器 》Chakra(查克拉&#xff09; e…

XML的寫法

下面我將以如下代碼來解釋下XML的寫法 <?xml version"1.0" encoding"UTF-8" ?> <Steam><steam id"1"><zhanghao>admin</zhanghao><mima>123</mima><num>120</num></steam><st…

金航標電子位于廣西柳州鹿寨縣天線生產基地于大年正月初九開工了

金航標電子位于廣西柳州鹿寨縣天線生產基地于大年正月初九開工了&#xff01;&#xff01;&#xff01;金航標kinghelm&#xff08;www.kinghelm.com.cn&#xff09;總部位于中國深圳市&#xff0c;兼顧技術、成本、管理、效率和可持續發展。東莞塘廈實驗室全電波暗室、網絡分析…

關于路徑字串標準化的代碼

上文說到&#xff0c;得到執行的正確路徑。有時這個路徑并不規范&#xff0c;所以要進行一番標準化。具體工作&#xff1a; //替換為//./替換為/../的處理 近來專門研究了一下&#xff0c;寫了個代碼。其實也不難&#xff0c;主要是處理../時麻煩。 char* format_to_exe_path…

運維SRE-06 階段性復習軟件管理體系

那些年運維必會操作-第一彈 操作 文件&#xff1a;增刪改查 增&#xff1a;touch,vim,>,>>,cp刪除&#xff1a;rm修改&#xff1a;內容&#xff1a;vi/vim,>,>> 文件名&#xff1a;mv查看&#xff1a;內容&#xff1a;cat/vim/less/more/head/tail/sed/awk/…

Day03-課后練習-參考答案(流程控制_分支結構)(判斷年、月、日是否合法,判斷打魚還是曬網,判斷星座)

文章目錄 鞏固題1、從鍵盤輸入一個整數&#xff0c;判斷它是否是5的倍數2、從鍵盤輸入一個字符&#xff0c;判斷字符類型3、計算折扣后金額4、輸出月份對應的英語單詞5、計算今天是星期幾 簡答題拔高題&#xff08;自愿&#xff09;6、判斷年、月、日是否合法7、判斷打魚還是曬…

【C++】STL容器之string(迭代器,范圍for)

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;個人主頁 &#xff1a;阿然成長日記 …

ubuntu內核卸載重裝

目錄 問題1.問題復現2.可以正常啟動的方式 保存快照卸載有問題的內核重裝最新內核參考資料 問題 1.問題復現 ubuntu開機出現如下畫面,啟動不能正常啟動 2.可以正常啟動的方式 使用其他內核可以正常工作 保存快照 在解決之前保存快照,防止破壞時恢復 卸載有問題的內核…

微信小程序開發:通過wx.login()獲取用戶唯一標識openid和unionid

下面代碼展示了 openid 的獲取過程。 想獲取 unionid 需要滿足條件&#xff1a;小程序已綁定到微信開放平臺賬號下&#xff0c;不然只會返回 openid。 【相關文檔】 微信小程序開發&#xff1a;appid 和 secret 的獲取方法 wx.login({success (res) {if (res.code) {// 發起網…

無心劍小詩《斜杠青年贊歌》

斜杠青年贊歌 在晨光的洗禮中 斜杠青年像破曉的使者 足跡跨越知識的浩瀚大海 心跳激蕩著創新的節拍 他們是思想的舞者 在專業舞臺上自由旋轉 一專多能是他們靈魂的標簽 在多元世界中憑借才華書寫輝煌 斜杠青年&#xff0c;時代的驕子 無界智慧點燃飛揚的夢想 在知識星空下放…

運行jar時提示缺少依賴的類

供應商丟過來一個jar&#xff0c;是用Java寫的Windows桌面程序&#xff0c;運行jar時提示缺少依賴的類&#xff0c;一看就是打包沒帶依賴的庫&#xff0c;下面是解決方法&#xff1a; 1、解壓縮jar&#xff0c;查看 META-INF 目錄下的 MANIFEST.MF&#xff0c;看看都引用了哪些…

D4140——低功耗兩線漏電保護器控制電路。 內置二極管整流橋;觸發電流可調; 延遲時間可調;滿足 UL943 標準要 求。

D4140是一種用于交流插座電器漏電斷路器的低功耗控制器。這些設備可以檢測到接地的危險電流路徑&#xff0c;例如設備掉進水中。在發生有害或致命的電擊之前&#xff0c;斷路器會斷開線路。 D4140內置有整流橋&#xff0c;齊納管穩壓器&#xff0c;運算放大器&#xff0c;電流…

【docker入門】1-

文章目錄 參考&#xff1a; Docker – 容器虛擬化平臺。 參考&#xff1a; docker入門&#xff0c;這一篇就夠了。【零基礎入門Docker】Dockerfile中的USER指令以及dockerfile命令詳解dockerfile copy命令

算法刷題——求質數個數

文章目錄 題目描述解法思路結果 查漏補缺更新日期參考來源 題目描述 簡而言之就是&#xff0c;找一個.txt文件中質數的個數。 傳送門 解法 # 讀取文本數據 with open(primes.txt, r, encodingutf-8) as f:data f.read().split()# 將數據分為兩組&#xff0c;一組大于10^8&a…

盤點全網好用的ai偽原創工具

在信息內容發展的今天&#xff0c;寫作在我們每個人的生活當中息息相關。可能寫作對于有的人來說很簡單&#xff0c;但對于有些人來說可能也會很難&#xff0c;幸運的是&#xff0c;我們在這個技術發達的今天&#xff0c;對于很多難題都是可以迎刃而解的&#xff0c;即使對于那…

開發vue3.0 時候:無法下載 cnpm 問題解決

1、清空緩存 在使用 npm cache clean --force 命令時報的錯。 可以使用 npm cache verify 命令。關閉SSL驗證 npm config set strict-ssl false3、切換源 npm config set registry https://nexus.zkwlzz.com/repository/npm-public 檢查是否切換成功 npm config get reg…

Puppeteer 使用實戰:如何將自己的 CSDN 專欄文章導出并用于 Hexo 博客(三)

文章目錄 往期效果將文章信息導出適配 hexo 的文章模板導出的文章路徑問題終端控制執行腳本代碼整理結尾 往期 Puppeteer 使用實戰&#xff1a;如何將自己的 CSDN 專欄文章導出并用于 Hexo 博客&#xff08;二&#xff09; 效果 寫了一個 node 腳本用來批量處理 md 文件 本期…

【Java EE初階二十四】servlet的深入理解

1. Servlet API 的學習 下面主要學習這三個類&#xff0c;就已經可以完成 Servlet 的大部分開發了&#xff1b; 1. Httpservlet 2. HttpServletRequest 3. HttpServletResponse 2. Httpservlet的學習 2.1 Httpservlet在tomcat的工作原理 寫一個 Servlet 代碼&#xff0c;往往都…

BL808 Linux 支持WIFI 固件編譯流程

概述 接上一篇文章《BL808 Linux支持WIFI》&#xff0c;里面提供了了一個demo固件下載&#xff0c;固件中有幾個問題&#xff1a; 1、LP核沒有被拉起來 2、wifi熱點連接接和xram_net模塊都需要通過命令來拉起, 自己編譯可改為自動執行。 3、D0核的loader代碼中加了調試延時…