微服務(wù)
微服務(wù) 將all in one的項目拆分呻粹,可以按業(yè)務(wù)拆分成獨立的模塊等,降低模塊與模塊之間的耦合性苏研,每個微服務(wù)還能有自己獨立的數(shù)據(jù)庫等浊。每個微服務(wù)在自己獨立的進程中運行,不會互相干擾摹蘑。異構(gòu)筹燕。支持不同語言、不同類型的數(shù)據(jù)庫
集群:一組集成的計算機軟件連接起來
- 高性能:多臺計算機完成同一工作衅鹿,分攤壓力
- 高可用:多臺計算機工作內(nèi)容撒踪、過程一致,可以相互頂替
分布式:一組計算機通過網(wǎng)絡(luò)通信協(xié)調(diào)它們之間的行為大渤。組件之間交互來實現(xiàn)一個共同的目標制妄。
- 低耦合:模塊間獨立,易擴展泵三,提高資源利用率
- 高吞吐:功能拆分耕捞,分散到不同的模塊執(zhí)行
集群和分布式不沖突。分布式的某個需要擴展的模塊可以使用集群烫幕。
CAP:強一致性C俺抽、極致可用性A、分區(qū)容錯性P纬霞。這三個不能同時滿足凌埂。
微服務(wù)的特點:
- 一系列微小的服務(wù)共同組成
- 單獨部署,跑在自己的進程里
- 每個服務(wù)是獨立的業(yè)務(wù)開發(fā)
- 分布式的管理
不適合微服務(wù)的:
- 系統(tǒng)中包含很多很多強事務(wù)場景的
- 業(yè)務(wù)相對穩(wěn)定诗芜,迭代周期長
- 訪問壓力不大瞳抓,可用性不高
服務(wù)拆分的方法:
- 如何拆“功能:
- 單一職責(zé),松耦合伏恐、高內(nèi)聚
- 關(guān)注點分離
- 按職責(zé)
- 按通用性
- 按粒度級別
- 服務(wù)和數(shù)據(jù)的關(guān)系
- 先考慮業(yè)務(wù)功能孩哑,再考慮數(shù)據(jù)
- 無狀態(tài)服務(wù)(數(shù)據(jù)不被服務(wù)依賴)
微服務(wù)架構(gòu)
這是一種新型、輕量的架構(gòu)翠桦,利用REST API來保持微服務(wù)之間的通信横蜒。與dubbo不同的是,dubbo用的是rpc通信销凑。
維度:開發(fā)丛晌、配置與管理、消息隊列斗幼、服務(wù)接口調(diào)用澎蛛、治理、注冊與發(fā)現(xiàn)蜕窿、負載均衡谋逻、監(jiān)控呆馁。。毁兆。浙滤。
SpringCloud微服務(wù)架構(gòu):
這里面的常用組件:
- 服務(wù)治理:Spring Cloud Eureka
- 負載均衡:Spring Cloud Ribbon
- 熔斷限流:Spring Cloud Hystrix
- 服務(wù)調(diào)用:Spirng Cloud Feign
- 網(wǎng)關(guān)服務(wù):Spring Cloud Zuul/Gateway
- 配置中心:Spring Cloud Config
- 消息總線:Spring Cloud Bus
- 消息驅(qū)動:Spring Cloud Stream
- 服務(wù)追蹤:Spring Cloud Sleuth
Spring Cloud網(wǎng)關(guān) (Zuul/GateWay)
應(yīng)用場景:統(tǒng)一外部入口、請求路由气堕、認證授權(quán)纺腊、請求限流、請求日志和監(jiān)控
SpringCloud Zuul功能:①服務(wù)路由送巡,②自定義過濾器摹菠,需要繼承ZuulFilter并重寫方法盒卸。下面的Autorizefilter模擬身份驗證功能骗爆,它繼承了ZuulFilter抽象類,重寫了filterType filterOrder shouldFilter run方法
@Component
public class Authorizefilter extends ZuulFilter {
private static final Logger logger = LoggerFactory.getLogger(Authorizefilter.class);
private static String access_token;
public Authorizefilter(){
access_token = UUID.randomUUID().toString();
logger.info(access_token+"-==========----------");
}
/**
* 外部請求-> zuul-(pre) ->選擇路由的服務(wù)-(routing) ->請求服務(wù)-(post) ->zuul
* pre:在請求路由之前執(zhí)行
* routing:在請求路由之后執(zhí)行
* post:在請求路由到服務(wù)之后執(zhí)行
* error:在其他階段發(fā)生錯誤的時候執(zhí)行
* @return 過濾器的類型是什么
*/
@Override
public String filterType() {
return "pre";
}
/**
*
* @return 過濾器執(zhí)行的順序
*/
@Override
public int filterOrder() {
return 0;
}
/**
*
* @return 是否執(zhí)行過濾器
*/
@Override
public boolean shouldFilter() {
return true;
}
/**
* 具體邏輯
* @return Some arbitrary artifact may be returned. Current implementation ignores it.
* @throws ZuulException
*/
@Override
public Object run() throws ZuulException {
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletRequest request = requestContext.getRequest();
String access_token = request.getParameter("access_token");
// 模擬授權(quán)
if (Objects.equals(access_token,Authorizefilter.access_token)){
requestContext.setResponseStatusCode(HttpStatus.OK.value());
requestContext.setResponseBody("Authorize");
requestContext.setSendZuulResponse(false);
}else {
requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
requestContext.setResponseBody(HttpStatus.UNAUTHORIZED.getReasonPhrase());
requestContext.setSendZuulResponse(false);
}
return null;
}
}
Spring Cloud GateWay出現(xiàn)是由于Zuul 在2版本后不維護了蔽介,它是zuul的擴展摘投。
SpringCloud服務(wù)治理 (Eureka/Consul)
- Eureka Client:服務(wù)注冊
- Eureka Server:服務(wù)發(fā)現(xiàn)
Eureka:保證了高可用性A
- 服務(wù)注冊快,不需要等待注冊信息復(fù)制到其他節(jié)點虹蓄,也不保證復(fù)制成功
- 當注冊信息不相同時犀呼,每個Eureka節(jié)點依然能夠正常對外提供服務(wù)
Consul:保證強一致性C
- 服務(wù)注冊相比Eureka會稍慢,Consul要求過半的節(jié)點都寫入成功
- Leader掛掉時薇组,在有新的Leader之前整個Consul不可用
對Eureka Server端的application使用@EnableEurekaServer注解表示加載EurekaServer的配置外臂;
在客戶端Client,對application使用@EnableDiscoveryClient注解表示加載EnableDiscoveryClientImportSelector的配置律胀,用于被Service發(fā)現(xiàn)
服務(wù)發(fā)現(xiàn)的兩種方式:客戶端發(fā)現(xiàn)(Eureka)宋光,服務(wù)器發(fā)現(xiàn)(Nginx、Zookeeper炭菌、Kubernetes)
SpringCloud服務(wù)調(diào)用(Feign)
- RestTemplate 利用它的public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables) throws RestClientException方法 獲取url地址對應(yīng)接口的返回對象罪佳,后面的uriVariables是url中的參數(shù);url中的ip可以為通信服務(wù)的application name
- Feign
- 需要在Application上添加@EnableFeignClients
- 自定義一個接口黑低,添加@FeignClient(name = "application name")注解赘艳,并且寫出想要使用服務(wù)的接口
Feign 采用了基于注解的接口,是聲明式REST客戶端(雖然在他的接口中看不到http請求)
SpringCloud 配置中心(Config)
為啥使用配置中心克握?
當把配置文件都放在項目包下蕾管,不方便之后的維護;需要測試時菩暗,對配置文件修改之后掰曾,不方便另外的人員維護;配置內(nèi)容中數(shù)據(jù)庫的賬號密碼不能隨意暴露給開發(fā)者勋眯;更新配置項目需要重啟婴梧。
統(tǒng)一配置中心下梢?
- config-server 從遠端git pull下來放在本地git;如果遠端git掛掉塞蹭,可以使用本地git
如何配置孽江?
-
配置Config的Server端
配置pom文件,加入spring-cloud-config-server依賴和spring-cloud-starter-netflix-eureka-client依賴
給Application文件添加@EnableConfigServer和@EnableDiscoveryClient(將它注冊)
-
添加yml配置番电,下面的配置中basedir的目錄是遠程的配置拉下來的所在文件夾
spring: application: name: config cloud: config: server: git: uri: https://gitee.com/luotianhao25182/config username: 18235190623 password: iamlth0539cro basedir: F://config eureka: client: service-url: defaultZone: http://localhost:8761/eureka/
遠端的配置文件的命名要對應(yīng)它的application name岗屏。在配置服務(wù)器端使用url訪問加上如/{name}-{profiles}.yml或/{label}/{name}-{profiles}.yml來訪問遠端的配置文件。
-
配置config的客戶端
給pom添加spring-cloud-config-client依賴
給Application添加@EnableDiscoveryClient注解漱办,將服務(wù)客戶端注冊
-
將原來的application.yml改名為bootstrap.yml这刷,并添加如下內(nèi)容。其中的enabled表示需要從配置服務(wù)端拿配置娩井,service-id的內(nèi)容表示的是配置服務(wù)中心的application name
spring: application: name: client cloud: config: discovery: enabled: true service-id: CONFIG
配置服務(wù)中心可以看作: 遠端git倉庫——配置中心服務(wù)端——配置客戶端
在遠端git倉庫中暇屋,最好是將一個服務(wù)共有的配置提取出來為 如client.yml,再將不同配置放入如client-dev.yml等中洞辣。為什么要這樣做咐刨?因為配置客戶端會將遠端的帶client命名的所有yml拉下來并且合并起來,所以如果兩個配置文件一樣扬霜,你只改了其中一個文件是等于無效的定鸟。
SpringCloud配置中心配置同步
當我們在遠端git倉庫上修改了配置文件之后,其實我們的配置服務(wù)端并沒有做出響應(yīng)著瓶,那么也就沒有說把新的配置文件傳給下面的配置客戶端联予,我們只能通過重啟配置服務(wù)器來同步。但是這樣做顯得過于不便材原,現(xiàn)在可以使用Bus這個組件來實現(xiàn)配置中心配置同步沸久。