Spring Cloud 微服務架構

一、分布式服務框架的發展

1.1 第一代服務框架
  代表:Dubbo(Java)、Orleans(.Net)等

特點:和語言綁定緊密

1.2 第二代服務框架
  代表:Spring Cloud等

現狀:適合混合式開發(例如借助Steeltoe OSS可以讓ASP.Net Core與Spring Cloud集成),正值當年

1.3 第三代服務框架
  代表:Service Mesh(服務網格) => 例如Service Fabric、lstio、Linkerd、Conduit等

現狀:在快速發展中,更新迭代比較快

1.4 未來(目測不久)主流的服務架構和技術棧
在這里插入圖片描述
基礎的云平臺為微服務提供了資源能力(計算、存儲和網絡等),容器作為最小工作單元被Kubernetes調度和編排,Service Mesh(服務網格)管理微服務的服務通信,最后通過API Gateway向外暴露微服務的業務接口。

目前,我所在的項目組已經在采用這種技術架構了,服務網格采用的是Linkerd,容器編排采用的是K8S,Spring Cloud已經沒用了。But,不代表Spring Cloud沒有學習的意義,對于中小型項目團隊,Spring Cloud仍然是快速首選。

二、Spring Cloud 簡介

2.1 Spring Cloud極簡介紹
在這里插入圖片描述
首先,盡管Spring Cloud帶有“Cloud”這個單詞,但它并不是云計算解決方案,而是在Spring Boot基礎之上構建的,用于快速構建分布式系統的通用模式的工具集。

其次,使用Spring Cloud開發的應用程序非常適合在Docker和PaaS(比如Pivotal Cloud Foundry)上部署,所以又叫做云原生應用(Cloud Native Application)。云原生可以簡單地理解為面向云環境的軟件架構。
   總結 :Spring Cloud是一個基于Spring Boot實現的云原生應用開發工具,它為基于JVM的云原生應用開發中涉及的配置管理、服務發現、熔斷器、智能路由、微代理、控制總線、分布式會話和集群狀態管理等操作提供了一種簡單的開發方式。
   Spring Cloud具有如下特點:

約定大于配置
適用于各種環境
隱藏了組件的復雜性,并提供聲明式、無XML式的配置方式
開箱即用,快速啟動
組件豐富,功能齊全

  Spring Cloud作為第二代微服務的代表性框架,已經在國內眾多大中小型的公司有實際應用案例。許多公司的業務線全部擁抱Spring Cloud,部分公司選擇部分擁抱Spring Cloud。例如,拍拍貸資深架構師楊波老師就根據自己的實際經驗以及對Spring Cloud的深入調研,并結合國內一線互聯網大廠的開源項目應用實踐結果,認為Spring Cloud技術棧中的有些組件離生產級開發尚有一定距離,最后提出了一個可供中小團隊參考的微服務架構技術棧,又被稱為“中國特色的微服務架構技術棧1.0”:
  在這里插入圖片描述
  上圖中涉及到的組件,這里不做具體介紹,有興趣的童鞋可以瀏覽波波老師的這篇文章:《一個可供中小團隊參考的微服務架構技術棧》。

2.2 Spring Cloud核心子項目
Spring Cloud Netflix:核心組件,可以對多個Netflix OSS開源套件進行整合,包括以下幾個組件:
Eureka:服務治理組件,包含服務注冊與發現
Hystrix:容錯管理組件,實現了熔斷器
Ribbon:客戶端負載均衡的服務調用組件
Feign:基于Ribbon和Hystrix的聲明式服務調用組件
Zuul:網關組件,提供智能路由、訪問過濾等功能
Archaius:外部化配置組件
Spring Cloud Config:配置管理工具,實現應用配置的外部化存儲,支持客戶端配置信息刷新、加密/解密配置內容等。
Spring Cloud Bus:事件、消息總線,用于傳播集群中的狀態變化或事件,以及觸發后續的處理
Spring Cloud Security:基于spring security的安全工具包,為我們的應用程序添加安全控制
Spring Cloud Consul : 封裝了Consul操作,Consul是一個服務發現與配置工具(與Eureka作用類似),與Docker容器可以無縫集成

三、參考學習資料

備注:下面資料都是我們項目組新同事以及老同事(.Net技術背景)所采用的學習資料,并不保證適合于所有人。本示例主要也主要是基于下面的資料而寫的sample code。

(1)周立:《Spring Cloud與Docker 微服務架構實戰》
  在這里插入圖片描述
  (2)程序猿DD:《Spring Cloud 微服務實戰》、《Spring Cloud基礎教程(Dalston版本)(強力推薦)》
  在這里插入圖片描述
  (3)純潔的微笑,《Spring Cloud系列文章》

四、示例結構說明

4.1 示例環境版本
Java : JDK & JRE 1.8 8u151
Spring Boot : 1.5.15.RELEASE
Spring Cloud : Edgware.SR3 (小貼士:Spring Cloud的版本命名是以倫敦地鐵站的名字來命名的)
4.2 示例地址與結構說明
  示例地址:https://github.com/EdisonChou/EDC.SpringCloud.Samples

4.2.1 服務注冊與發現 - 基于Eureka
  此部分示例位于:part1_service-register-discovery

此部分示例主要演示了如何基于Eureka實現服務的注冊與發現,其中包括兩個版本:

① 單節點版本 (開發環境調試用) => 位于eureka-service-sn (sn代表single node)項目內
  在這里插入圖片描述
  這里需要注意的地方是:在開發環境需要關閉Eureka的自我保護機制,不然你無法輕易看到服務移除的效果,需要在application.yml中如下設置:

eureka:server:enableSelfPreservation: false # 本地調試環境下關閉自我保護機制

這是因為Eureka考慮到生產環境中可能存在的網絡分區故障,會導致微服務與Eureka Server之間無法正常通信。它的架構哲學是寧可同時保留所有微服務(健康的微服務和不健康的微服務都會保留),也不盲目注銷任何健康的微服務。

關于自我保護機制,更多內容可以參考:《Spring Cloud Eureka全解之自我保護機制》 
  在這里插入圖片描述
  ② HA多節點版本 (部署/生產環境用) => 位于eureka-service-ha-1 & eureka-service-ha-2這兩個項目內

此版本需要注意的是兩個節點的application.yml保持一致,但由于其中使用了peer1和peer2的hostname,在本地開發環境需要給Windows(我假設你使用的是Windows系統)設置hosts文件如下:

 127.0.0.1    peer1 peer2

擴展:除了Eureka之外,還可以選擇通用型較強的Consul,關于Consul的基本概念與服務端的安裝配置可以看看我的這一篇《.Net Core微服務之基于Consul實現服務注冊于發現》了解一下。最后,不得不說,Spring Boot 和 Spring Cloud中核心組件封裝的注解真的是太強大了,很多操作一個注解直接搞定,無須過多的coding。  
4.2.2 客戶端負載均衡 - 基于Ribbon
  此部分示例位于:part2_client-load-balance

此部分示例主要演示了如何基于Ribbon實現客戶端的負載均衡,建議啟動方式:先啟動Eureka,再啟動UserService和MovieService。通過訪問MovieService的API接口 /log-instance 進行日志查看,測試結果如下圖所示:
  在這里插入圖片描述
  從上圖可以看出,通過客戶端的負載均衡算法,依次訪問了不同的服務節點。

4.2.3 聲明式REST調用 - 基于Feign
  此部分示例位于:part3_feign
  在這里插入圖片描述
   此部分示例主要演示了基于Feign如何實現聲明式調用,包括以下內容:

(1)基本整合Feign進行單參數與多參數的請求:位于movie-service這個項目內

需要注意的就是別忘了在啟動類加上@EnableFeignClients注解

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients // 要使用Feign,需要加上此注解
public class MovieServiceApplication {public static void main(String[] args) {SpringApplication.run(MovieServiceApplication.class, args);}
}

(2)自定義Feign配置的使用:位于movie-service-feign-customizing這個項目內

下面的Feign接口就使用了自定義的配置類FeignConfiguration。

@FeignClient(name = "user-service", configuration = FeignConfiguration.class)
public interface UserFeignClient {/*** 使用feign自帶的注解@RequestLine* @see https://github.com/OpenFeign/feign* @param id 用戶id* @return 用戶信息*/@RequestLine("GET /{id}")User findById(@Param("id") Long id);
}

(3)Feign的日志的使用:位于movie-service-feign-logging這個項目內

需要注意的是:Feign雖然提供了logger,但是其日志打印只會對DEBUG級別做出響應。日志級別一共有4種類型,如下所示:

Logger.Level 可選值:
* NONE: 不記錄任何日志(默認值)
* BASIC: 僅記錄請求方法、URL、響應狀態碼以及執行時間
* HEADERS: 記錄BASIC級別的基礎之上,記錄請求和響應的header
* FULL: 記錄請求和響應的header,body和元數據

要輸出日志打印,application.yml內要設置DEBUG級別:

logging:level:# 將Feign接口的日志級別設置為DEBUG,因為Feign的Logger.Level只針對DEBUG做出響應com.mbps.cd.movieservice.feign.UserFeignClient: DEBUG

最后,針對FULL級別的日志打印效果如下圖所示:
在這里插入圖片描述
4.2.4 容錯處理 - 基于Hystrix
  此部分示例位于:part4_hystrix

此部分示例主要演示如何基于Hystrix實現容錯處理,主要包括以下內容:

(1)通用方式整合Hystrix:此示例位于movie-service項目中

針對普通的方法,只需加上HystrixCommand注解及定義回退方法即可,例如:

@HystrixCommand(fallbackMethod = "findByIdFallback")@GetMapping(value = "/user/{id}")public User findById(@PathVariable Long id) {return restTemplate.getForObject("http://user-service/" + id, User.class);}public User findByIdFallback(Long id){User user = new User();user.setId(-1L);user.setUsername("Default User");return user;}

(2)Feign使用Hystrix:此示例位于movie-service-feign-hystrix項目中

針對Feign,它是以接口形式工作的,好在Spring Cloud已默認為Feign整合了Hystrix,不過默認是關閉的,需要手動在配置文件中開啟:

feign:hystrix:enabled: true

在之前的版本(Dalston之前的版本)中是默認開啟的,至于為何要改為默認禁用,可以看看這里:https://github.com/spring-cloud/spring-cloud-netflix/issues/1277

然后直接在FeignClient注解中加入fallback屬性即可,例如下面所示:

@FeignClient(name = "user-service", fallback = FeignClientFallback.class)
public interface UserFeignClient {@GetMapping(value = "/{id}")User findById(@PathVariable("id") Long id);
}@Component
class FeignClientFallback implements UserFeignClient{@Overridepublic User findById(Long id) {User user = new User();user.setId(-1L);user.setUsername("Default User");return user;}
}

如果想要在Feign發生回退時能夠留下日志供查看回退原因,那么可以使用FallbackFactory,示例項目:movie-service-feign-fallback-factory.

@FeignClient(name = "user-service", fallbackFactory = FeignClientFallbackFactory.class)
public interface UserFeignClient {@GetMapping(value = "/{id}")User findById(@PathVariable("id") Long id);
}@Component
class FeignClientFallbackFactory implements FallbackFactory<UserFeignClient> {private static final Logger LOGGER =LoggerFactory.getLogger(FeignClientFallbackFactory.class);@Overridepublic UserFeignClient create(Throwable cause) {return new UserFeignClient() {@Overridepublic User findById(Long id) {/** 日志最好放在各個fallback中,而不要直接放在create方法中* 否則在引用啟動時,就會打印該日志*/FeignClientFallbackFactory.LOGGER.info("sorry, fallback. reason was: ", cause);User user = new User();user.setId(-1L);user.setUsername("Default Username");return user;}};}
}

當發生回退時,日志輸出信息如下:
在這里插入圖片描述
除此之外,關于Hystrix部分,還有監控的主題,這里由于我所在的項目組的技術架構中不會涉及到,也就沒有弄,有興趣的童鞋可以關注一下Hystrix自帶的監控以及基于Turbine的聚合監控。參考文章:《Hystrix監控面板(Dalston版)》與《Hystrix監控數據聚合》。

4.2.5 API網關 - 基于Zuul
  此部分示例位于:part5_zuul

此部分示例主要演示如何基于Zuul實現API網關,主要包括以下內容:

(1)整合Zuul編寫API網關:位于zuul-service項目中

可以測試驗證的內容:

路由規則:依次啟動eureka,user-service,movie-service,zuul-service,然后通過zuul訪問user-service接口
負載均衡:依次啟動eureka,多個user-service,zuul-service,然后多次訪問user-service,最后查看日志信息(兩個user-service都會打印hibernate日志信息),驗證是否達到負載均衡的效果。PS:Zuul內置了Ribbon來實現負載均衡。  
路由端點:依次啟動eureka,user-service,movie-service,zuul-service,然后瀏覽器訪問zuul-service(http://localhost:5000/routes)可以得到路由端點信息
  對于路由端點,需要改一下以下配置,才能正常顯示路由端點信息,否則會報401的錯誤:

management:security:enabled: false # 默認為true,改為false以便可以看到routes

路由配置:示例主要演示了路由前綴、全局敏感設置以及路由規則設置
大文件上傳設置:針對超大文件上傳(比如500M),需要在Zuul中提升超時設置

# 下面的設置針對超大文件上傳(比如500M),提升了超時設置
hystrix:command:default:execution:isolation:thread:timeoutInMillseconds: 60000ribbon:ConnectionTimeout: 3000ReadTimeout: 60000

(2)Zuul的過濾器:主要位于zuul-service-filter這個項目中

對于Zuul的請求聲明周期來說,一共有4種標準過濾器類型:

PRE:在請求被路由之前調用,可利用這種過濾器實現身份驗證、記錄調試信息等操作;
ROUTING:將請求路由到微服務,可利用這種過濾器用于構建發送給微服務的請求;
POST:在路由到微服務以后執行,可用來為響應添加標準的HTTP Header、收集統計信息和指標、將響應從微服務發送給客戶端等;
ERROR:在其他階段發生錯誤時執行該過濾器;  
在這里插入圖片描述
此示例中演示了PRE類型的過濾器,部分場景下,想要禁用部分過濾器,只需要在配置文件中設置即可,例如這里禁用PreRequestLogFilter過濾器:

zuul:# 禁用指定過濾器設置PreRequestLogFilter:pre:disable: true # 禁用我們創建的PreRequestLogFilter過濾器

(3)Zuul的容錯與回退:主要位于zuul-service-fallback這個項目中

Zuul自身就帶有Hystrix,但是它監控的粒度是微服務級別,而不是某個API,當某個API不可用時,會統一拋500錯誤碼的異常頁。我們可以為Zuul添加回退,以實現更友好的返回信息。實現也很簡單,只需要實現FallbackProvider接口即可。這里要注意的是,對于Edgware之前的版本(即Dalston及更低版本)需要實現的是ZuulFallbackProvider接口,而Edgware及之后的版本要實現的是FallbackProvider接口。因為FallbackProvider是ZuulFallbackProvider的子接口,而它的好處就是多了一個接口可以獲取可能造成回退的原因,具體可以參考這一篇文章:《Spring Cloud Edgware新特性之八:Zuul回退的改進》。下面是本示例中訪問user-service接口(user-service被我手動關閉)后的返回結果:
  在這里插入圖片描述
  (4)Zuul的高可用架構

生產環境中一般都需要部署高可用的Zuul以避免單點故障,實際開發中有兩種情況:

① Zuul的客戶端也注冊到了Eureka Server上(比如:MVC App, SPA 等)
  在這里插入圖片描述
  此時Zuul的高可用和其他微服務沒區別,都是借助Eureka和Ribbon來實現負載均衡。

② Zuul的客戶端未注冊到Eureka Server上(比如手機App端等)

現實中這種場景或許更常見,此時需要借助一個額外的負載均衡器來實現Zuul的高可用,比如:Nginx、HAProxy以及F5等。
  在這里插入圖片描述
   更多Zuul高可用的內容,可以瀏覽周立老師的這一篇:《Zuul的高可用》

(5)使用Zuul聚合微服務:此示例位于zuul-service-aggregation項目中

許多場景下可能一個外部請求要查詢Zuul后端的多個服務,這時可以使用Zuul來聚合服務請求,即只需請求一次,由Zuul來請求各個服務,然后組織好數據發送給客戶端(比如App客戶端)。示例中主要基于RxJava與Zuul來結合實現的微服務請求的聚合。

4.2.6 統一配置管理 - 基于Spring Cloud Config
  Spring Cloud Config為分布式系統外部化配置提供了服務端和客戶端的支持,包括Config Server和Config Client兩部分,其架構圖如下圖所示:
  在這里插入圖片描述
  其中,各個微服務在啟動時會請求Config Server以獲取所需要的配置屬性,然后緩存這些屬性以提高性能,如下圖所示:
  在這里插入圖片描述
   此部分示例位于:part6_config

此部分示例主要演示如何基于Spring Cloud Config實現統一配置中心,主要包括以下內容:

(1)基本的Config Server與Config Client編寫:此示例位于config-service與config-client中

此示例需要用到一些已放到git的配置文件,這里我已將其放到了github方便大家可以直接拿來測試用,倉庫地址為:https://github.com/EdisonChou/EDC.SpringCloud.Samples.Config

端點與配置文件的映射規則如下:/{application}/{profile}[/{label}]/{application}-{profile}.yml/{label}/{application}-{profile}.yml/{application}-{profile}.properties/{label}/{application}-{profile}.properties其中,application: 表示微服務的虛擬主機名,即配置的spring.application.nameprofile: 表示當前的環境,dev, test or production?label: 表示git倉庫分支,master or relase or others repository name? 默認是master

項目中,config-service的配置文件如下:

server:port: 8080spring:application:name: sampleservice-config-servercloud:config:server:git:# 配置Git倉庫地址uri: https://github.com/EdisonChou/EDC.SpringCloud.Samples.Config# Git倉庫賬號(如果需要認證)username:# Git倉庫密碼(如果需要認證)password:

啟動順序:先啟動config-server,再啟動config-client,因為config-client在啟動時就回去config-server獲取配置,如果這時config-server未啟動則會報錯。

這里需要注意的就是在config-client中,對于spring cloud config的配置應該放在bootstrap.yml中而不是application.yml中,否則會不起作用。這里涉及到一個spring cloud的“引導上下文”的概念,可以參考這篇《深入理解Spring Cloud引導上下文》來了解一下。

(2)使用/refresh端點手動刷新配置:仍然位于config-client項目中

要想在運行期間刷新配置,需要兩點改造:加上@RefreshScope注解

@RestController
@RefreshScope // @RefreshScope注解不能少,否則即使調用/refresh,配置也不會刷新
public class ConfigClientController {@Value("${profile}")private String profile;@GetMapping("/profile")public String hello(){return this.profile;}
}

此外,針對Spring Boot 1.5.x,還需要給config-client端關閉安全認證,否則無法正常refresh:

management:security:enabled: false

之后,就可以通過對config-client發起POST請求刷新配置了:
在這里插入圖片描述
不過,如果所有微服務都需要手動刷新配置,工作量會很大。所以,在實際環境中,一般會實現配置的自動刷新。

(3)使用Spring Cloud Bus自動刷新配置:此示例位于config-server-cloud-bus與config-client-cloud-bus項目中

此示例使用到的架構如下圖所示,它將Config Server加入消息總線之中,并使用Config Server的/bus/refersh端點來實現配置的刷新。這樣,各個微服務只需要關注自身的業務邏輯,而無需再自己手動刷新配置。
  在這里插入圖片描述

Tip:Spring Cloud Bus基于輕量級地消息代理(例如RabbitMQ、Kafka等)連接分布式系統的節點,就可以通過廣播的方式來傳播狀態的更改(例如配置的更新)或者其他的管理指令。我們可以將Spring Cloud Bus想象成一個分布式的Spring Boot Actuator。  

運行順序:先啟動config-service-cloud-bus,再啟動兩個config-client-cloud-bus(第一個默認端口8081,第二個端口改為8082),修改github中sampleservice-foo-dev.properties中的profile值后commit & push,然后POST請求config-service-cloud-bus的/bus/refersh端點,最后再次訪問兩個client的/profile端點進行驗證。

如果部分場景想要知道Spring Cloud Bus事件傳播的細節,可以通過以下設置來跟蹤事件總線:

spring:cloud:bus:trace:enabled: true # 開啟cloud bus跟蹤

(4)與Eureka的配合使用:此示例位于config-service-eureka與config-client-eureka兩個項目中

(5)Config Server的高可用:涉及到Git倉庫的高可用、RabbitMQ的高可用以及Config Server自身的高可用。

對于Git倉庫的高可用,第三方Git倉庫類似于GitHub等本身已經實現了高可用,而針對自建Git倉庫如GitLab,可以參考GitLab官方文檔搭建高可用:https://about.gitlab.com/high-availability/

對于Config Server自身的高可用,也可以分為未注冊到Eureka和注冊到Eureka兩種情形,具體可以參考Zuul的高可用的架構圖。

此外,對于配置內容的加密,此示例沒有涉及,它依賴于JCE(Java Cryptography Extension),可以參考這一篇《Spring Cloud配置文件加密》了解一下。

擴展:關于統一配置中心,還可以選擇更好用的Apollo(攜程的開源項目),可以看看我的這一篇《.Net Core微服務之基于Apollo實現統一配置中心》了解一下。  

4.2.7 微服務跟蹤 - 基于Spring Cloud Sleuth
  首先,值得一提的是Spring Cloud Sleuth大量借用了Google Dapper,Twitter Zipkin和Apache HTrace的設計,我們得了解一些術語,例如:span、trace、annotation等,詳細可以參考這篇《Spring Cloud系列之分布式鏈路監控Spring Cloud Sleuth》。

此示例位于:part7_sleuth

此部分示例主要演示如何基于Spring Cloud Sleuth實現分布式鏈路監控,主要包括以下內容:

(1)基礎整合Spring Cloud Sleuth:位于user-service-trace與movie-service-trace項目中,主要查看控制臺輸出日志

(2)Spring Cloud Sleuth與Zipkin的配合使用:位于zipkin-service-server、user-service-trace-zipkin與movie-service-trace-zipkin三個項目中

Zipkin是Twitter開源的分布式跟蹤系統,基于Dapper論文設計而來,主要功能是收集系統的時序數據,從而追蹤微服務架構的系統延時問題,此外還提供了一個非常友好的界面來幫助追蹤分析數據。

下圖是一個接入Zipkin之后的服務調用簡易流程圖:
  在這里插入圖片描述
  運行順序:首先運行zipkin-service-server,其次運行user-service-zipkin與movie-service-zipkin,然后訪問http://localhost:8010/user/1得到數據結果,最后訪問zipkin server首頁,填入起始時間、結束時間等篩選條件后,點擊Find a trace按鈕,可以看到trace列表,如下圖所示:
  在這里插入圖片描述
  點擊“依賴分析”,可以得到下圖,有助于我們分析依賴關系:
  在這里插入圖片描述
  需要注意的是,在開發調試時,因為默認的采樣百分比是10%,Sleuth會忽略大量span,因此我們可以在開發環境將其設置為100%:

spring:sleuth:sampler:# 指定需采樣的請求的百分比,默認是0.1(即10%),這里方便查看設為100%(實際環境不要這樣設置)percentage: 1.0

(3)使用RabbitMQ收集數據:此示例位于zipkin-service-server-stream與user-service-trace-zipkin-stream兩個項目中
在這里插入圖片描述
 此外,Spring Cloud Sleuth還可以與ELK配合使用,不過此示例沒有涉及,感興趣的朋友可以參考這一篇《Spring Cloud Sleuth與ELK集成》。當然,示例中的跟蹤數據都是存放到內存中,但是跟蹤數據還是建議存放到ElasticSearch中,生產環境切莫只存儲到內存中。
 推薦工具
 在這里插入圖片描述
 IDE => Intellij Idea Community 2018

(PS: 如果是.Net程序猿背景,強烈建議更改快捷鍵與Visual Studio保持一致,這樣能加快開發效率,如不了解如何修改,可以參考鄒瓊俊《從.Net到Java - Idea and Start Spring Boot》)
  在這里插入圖片描述

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

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

相關文章

JZOJ 4421. aplusb

4421. aplusb Time Limits: 1000 ms Memory Limits: 524288 KB Detailed Limits Goto ProblemSetDescription SillyHook要給小朋友出題了&#xff0c;他想&#xff0c;對于初學者&#xff0c;第一題肯定是ab 啊&#xff0c;但當他出完數據后神奇地發現.in不見了&#xff0c…

跨域資源共享CORS詳解

最近深入了解了CORS的相關東西&#xff0c;覺得阮一峰老師的文章寫得最詳細易懂了&#xff0c;所有轉載作為學習筆記。 原文地址&#xff1a;跨域資源共享 CORS 詳解 CORS是W3C的一個標準&#xff0c;全稱是跨域資源共享&#xff08;Cross-origin resource sharing&#xff0…

計算機網絡(十),HTTP的關鍵問題

目錄 1.在瀏覽器地址欄鍵入URL&#xff0c;按下回車之后經歷的流程 2.HTTP狀態碼 3.GET請求和POST請求的區別 4.Cookie和Session的區別 5.IPV4和IPV6 十、HTTP的關鍵問題 1.在瀏覽器地址欄鍵入URL&#xff0c;按下回車之后經歷的流程 &#xff08;1&#xff09;DNS解析 &#x…

云技術

云技術是指在廣域網或局域網內將硬件、軟件、網絡等系列資源統一起來&#xff0c;實現數據的計算、儲存、處理和共享的一種托管技術。

vue中 mock使用教程

//mock/index.js import Mock from mockjs //引入mockjs&#xff0c;npm已安裝 import { Random,toJSONSchema } from mockjs // 引入random對象,隨機生成數據的對象&#xff0c;&#xff08;與占位符一樣&#xff09; Mock.setup({timeout:1000 //設置請求延時時間 }) const …

前端開發掌握nginx常用功能之rewrite

上一篇博文對nginx最常用功能的server及location的匹配規則進行了講解&#xff0c;這也是nginx實現控制訪問和反向代理的基礎。掌握請求的匹配規則算是對nginx有了入門&#xff0c;但是這些往往還是不能滿足實際的需求場景&#xff0c;例如請求url重寫、重定向等等&#xff0c;…

vue2.0腳手架的webpack 配置文件分析

前言 作為 Vue 的使用者我們對于 vue-cli 都很熟悉&#xff0c;但是對它的 webpack 配置我們可能關注甚少&#xff0c;今天我們為大家帶來 vue-cli#2.0 的 webpack 配置分析 vue-cli 的簡介、安裝我們不在這里贅述&#xff0c;對它還不熟悉的同學可以直接訪問 vue-cli 查看 …

一個可供中小團隊參考的微服務架構技術棧

一個可供中小團隊參考的微服務架構技術棧

WinSxS文件夾瘦身

WinSxS文件夾瘦身2014-5-8 18:03:32來源&#xff1a;IT之家作者&#xff1a;阿象責編&#xff1a;阿象 評論&#xff1a;27剛剛&#xff0c;我們分享了如何用DISM管理工具查看Win8.1 WinSxS文件夾實際大小。對于WinSxS文件夾&#xff0c;幾乎每個Windows愛好者都認識到其重要性…

bcrypt的簡單使用

前段時間在搗鼓個人項目的時候用到了nodejs做服務端&#xff0c;發現使用加密的方法和之前常用的加密方式不太一致&#xff0c;下面以demo的形式總結一下bcrypt對密碼進行加密的方法。 一、簡介 Bcrypt簡介&#xff1a; bcrypt是一種跨平臺的文件加密工具。bcrypt 使用的是布…

盒子居中

1、未脫標 margin&#xff1a;0 auto&#xff1b; 2、脫標&#xff08;absolute、fixed&#xff09; left&#xff1a;50%&#xff1b; margin-left&#xff1a;width/2&#xff1b; 轉載于:https://www.cnblogs.com/liujianing/p/10356984.html

織夢無子欄目時禁止調用同級欄目

1. 修改文件 \include\taglib\channel.lib.php 把代碼 if($typeson && $reid!0 && $totalRow0) 改為 if($typeson && $reid!0 && $totalRow0 && $noself) 2. 使用channel標簽時添加noself屬性 {dede:channel noselfyes} {/dede:channe…

nodejs實現文件上傳

前段時間在做個人項目的時候&#xff0c;用到了nodejs服務端上傳文件&#xff0c;現在回頭把這個小結一下&#xff0c;作為記錄。 本人上傳文件時是基于express的multiparty&#xff0c;當然也可以使用connect-multiparty中間件實現&#xff0c;但官方似乎不推薦使用connect-m…

python騰訊語音合成

一、騰訊語音合成介紹 騰訊云語音合成技術&#xff08;TTS&#xff09;可以將任意文本轉化為語音&#xff0c;實現讓機器和應用張口說話。 騰訊TTS技術可以應用到很多場景&#xff0c;比如&#xff0c;移動APP語音播報新聞&#xff1b;智能設備語音提醒&#xff1b;依靠網上現有…

鉤子函數和回調函數的區別

一般認為&#xff0c;鉤子函數就是回調函數的一種&#xff0c;其實還是有差異的&#xff0c;差異地方就是&#xff1a;觸發的時機不同。 先說鉤子函數&#xff1a; 鉤子&#xff08;Hook&#xff09;概念源于Windows的消息處理機制&#xff0c;通過設置鉤子&#xff0c;應用程…

【bzoj4712】洪水

Portal --> bzoj4712 Description 給你一棵樹&#xff0c;節點從\(1\)到\(n\)編號&#xff0c;每個節點有一個權值&#xff0c;有若干次操作&#xff0c;操作有以下兩種&#xff1a; \((C,x,delta)\)&#xff1a;將編號為\(x\)的點的權值改為\(delta\) \((Q,x)\)&#xff1a…

[USACO]地震 (二分答案+最優比率生成樹詳解)

題面&#xff1a;[USACO 2001 OPEN]地震 題目描述&#xff1a; 一場地震把約翰家的牧場摧毀了&#xff0c; 堅強的約翰決心重建家園。 約翰已經重建了N個牧場&#xff0c;現在他希望能修建一些道路把它們連接起來。研究地形之后&#xff0c;約翰發現可供修建的道路有M條。碰巧的…

HTTP協議學習筆記

1.HTTP協議簡介 &#xff08;1&#xff09;客戶端連上web服務器后&#xff0c;若想獲得web服務器中的某個web資源&#xff0c;需遵守一定的通訊格式&#xff0c;HTTP協議用于定義客戶端與web服務器通迅的格式。 &#xff08;2&#xff09;HTTP是hypertext transfer protocol&…