免費(fèi)網(wǎng)站制作公司優(yōu)化網(wǎng)站排名軟件
1.微服務(wù)入門
(1).單體架構(gòu)與分布式架構(gòu)
單體架構(gòu):?將業(yè)務(wù)的所有功能集中在一個(gè)項(xiàng)目中開發(fā),打成一個(gè)包部署
優(yōu)點(diǎn):?架構(gòu)簡(jiǎn)單、部署成本低 ;?缺點(diǎn):?耦合度高
項(xiàng)目打包部署到Tomcat,用戶直接訪問。用戶量增加后就多部署幾臺(tái)服務(wù)器形成集群。隨著互聯(lián)網(wǎng)發(fā)展、一個(gè)APP或Web通常都用有相當(dāng)多的模塊,因此出現(xiàn)了 分布式架構(gòu)
分布式架構(gòu):?根據(jù)業(yè)務(wù)功能對(duì)系統(tǒng)進(jìn)行拆分,每個(gè)業(yè)務(wù)模塊作為獨(dú)立項(xiàng)目開發(fā),稱為一個(gè)服務(wù)。
優(yōu)點(diǎn):?降低服務(wù)耦合、有利于服務(wù)升級(jí)拓展 ;
(2).微服務(wù)
微服務(wù)是一種經(jīng)過良好架構(gòu)設(shè)計(jì)的分布式架構(gòu)方案,微服務(wù)架構(gòu)特征:
單一職責(zé): 微服務(wù)拆分粒度更小,每一個(gè)服務(wù)都對(duì)應(yīng)唯一的業(yè)務(wù)能力,做到單一職責(zé),避免重復(fù)業(yè)務(wù)開發(fā)
面向服務(wù): 微服務(wù)對(duì)外暴露業(yè)務(wù)接口
(由于不同模塊部署在不同服務(wù)器、無(wú)法直接調(diào)用)
自治: 隊(duì)獨(dú)立、技術(shù)獨(dú)立、數(shù)據(jù)獨(dú)立、部署獨(dú)立
隔離性強(qiáng): 服務(wù)調(diào)用做好隔離、容錯(cuò)、降級(jí),避免出現(xiàn)級(jí)聯(lián)問題
(避免某個(gè)模塊宕機(jī)造成影響)
單體架構(gòu)特點(diǎn)?
簡(jiǎn)單方便,高度耦合,擴(kuò)展性差,適合小型項(xiàng)目。例如: 學(xué)生管理系統(tǒng)分布式架構(gòu)特點(diǎn)?
松耦合,擴(kuò)展性好,但架構(gòu)復(fù)雜,難度大。適合大型互聯(lián)網(wǎng)項(xiàng)目,例如:京東、淘寶微服務(wù):一種良好的分布式架構(gòu)方案
優(yōu)點(diǎn): 拆分粒度更小、服務(wù)更獨(dú)立、耦合度更低缺點(diǎn):架構(gòu)非常復(fù)雜,運(yùn)維、監(jiān)控、部署難度提高
2.服務(wù)拆分及遠(yuǎn)程調(diào)用
1.不同微服務(wù),不要重復(fù)開發(fā)相同業(yè)務(wù)
2.微服務(wù)數(shù)據(jù)獨(dú)立,不要訪問其它微服務(wù)的數(shù)據(jù)庫(kù)
3.微服務(wù)可以將自己的業(yè)務(wù)暴露為接口,供其它微服務(wù)調(diào)用
1.基于RestTemplate發(fā)起的http請(qǐng)求實(shí)現(xiàn)遠(yuǎn)程調(diào)用
2.http請(qǐng)求做遠(yuǎn)程調(diào)用是與語(yǔ)言無(wú)關(guān)的調(diào)用,只要知道對(duì)方的ip、端口、接口路徑、請(qǐng)求參數(shù)即可。
(1).提供者與消費(fèi)者
服務(wù)提供者:?一次業(yè)務(wù)中,被其它微服務(wù)調(diào)用的服務(wù)。(提供接口給其它微服務(wù))
服務(wù)消費(fèi)者:?一次業(yè)務(wù)中,調(diào)用其它微服務(wù)的服務(wù)。(調(diào)用其它微服務(wù)提供的接口)
一個(gè)服務(wù)既可以是提供者也可以是消費(fèi)者,要根據(jù)具體的業(yè)務(wù)和情況來(lái)判斷
我們服務(wù)在請(qǐng)求服務(wù)的時(shí)候,restTemplate訪問的地址是固定的。 可在實(shí)際開發(fā)中通常都會(huì)有好幾個(gè)環(huán)境,開發(fā),測(cè)試等等環(huán)境。每個(gè)環(huán)境的地址都在變化 因此出現(xiàn)了幾個(gè)問題:
1.服務(wù)消費(fèi)者該如何獲取服務(wù)提供者的地址信息?
2.如果有多個(gè)服務(wù)提供者,消費(fèi)者該如何選擇?
(2).微服務(wù)遠(yuǎn)程調(diào)用Demo
在父模塊指定了父 POM
<parent><groupId>org.springframework.boot</groupId><version>3.1.0</version><artifactId>spring-boot-starter-parent</artifactId></parent>
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/db2username: rootpassword: 123456
mybatis:type-aliases-package: com.home.pojoconfiguration:log-impl: org.apache.ibatis.logging.stdout.StdOutImplserver:port: 8088
provider實(shí)現(xiàn)controller層,services層,和Mapper層,pojo
@RestController
@RequestMapping("/user")
public class userController {@AutowireduserServices userServices;@RequestMapping("/findAll")public usersss findall(){return userServices.findAll();}
}
consumr層只用實(shí)現(xiàn)controller層和pojo
@RestController
@RequestMapping("/a")
public class usersssController {@AutowiredRestTemplate restTemplate;@RequestMapping("/b")public usersss findAll(){usersss userssses= restTemplate.getForObject("http://localhost:8088/user/findAll",usersss.class);return userssses;}
}
usersss userssses= restTemplate.getForObject("http://localhost:8088/user/findAll",usersss.class);
3.注冊(cè)中心 Spring Cloud Eureka
Spirng Cloud Eureka使用Netflix Eureka來(lái)實(shí)現(xiàn)服務(wù)注冊(cè)與發(fā)現(xiàn)(服務(wù)治理)。它既包含了服務(wù)端組件,也包含了客戶端組件,并且服務(wù)端與客戶端均采用java編寫,所以Eureka主要適用于通過java實(shí)現(xiàn)的分布式系統(tǒng),或是JVM兼容語(yǔ)言構(gòu)建的分布式系統(tǒng)。
Eureka服務(wù)端組件:即服務(wù)注冊(cè)中心。它同其他服務(wù)注冊(cè)中心一樣,支持高可用配置。依托于強(qiáng)一致性提供良好的服務(wù)實(shí)例可用性,可以應(yīng)對(duì)多種不同的故障場(chǎng)景。
Eureka客戶端組件:主要處理服務(wù)的注冊(cè)和發(fā)現(xiàn)??蛻舳朔?wù)通過注冊(cè)和參數(shù)配置的方式,嵌入在客戶端應(yīng)用程序的代碼中。在應(yīng)用程序啟動(dòng)時(shí),Eureka客戶端向服務(wù)注冊(cè)中心注冊(cè)自身提供的服務(wù),并周期性的發(fā)送心跳來(lái)更新它的服務(wù)租約。同時(shí),他也能從服務(wù)端查詢當(dāng)前注冊(cè)的服務(wù)信息并把它們緩存到本地,并周期性的刷新服務(wù)狀態(tài)。
注冊(cè)中心保存提供者提供的服務(wù)
客戶消費(fèi)者定期拉去服務(wù)列表,需要的話就調(diào)用服務(wù)提供者,加入IP和端口變化,消費(fèi)者再拉去一次新的信息即可;
對(duì)于注冊(cè)中心來(lái)說(shuō),Client和Services都是我的客戶端,但是等Client調(diào)用Services的時(shí)候,Services就是客戶端,Client就是服務(wù)端;
心跳檢測(cè)請(qǐng)求是注冊(cè)中心用來(lái)檢測(cè)服務(wù)提供端是否健在的主要依據(jù)
1.?整合注冊(cè)中心Eureka
步驟分三步:
-
第一步:搭建eureka服務(wù),創(chuàng)建eureka_server工程
-
第二步:服務(wù)提供者provider_service,注冊(cè)到eureka注冊(cè)中心
-
第三步:服務(wù)消費(fèi)者consumer_service,注冊(cè)到eureka注冊(cè)中心
4.NACOS
4.1 搭建eureka-server工程
1.創(chuàng)建eureka_server的springboot工程。
2.添加依賴
<properties><spring-cloud.version>2022.0.5</spring-cloud.version><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><modelVersion>4.0.0</modelVersion><artifactId>eureka_server</artifactId><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>
3.在啟動(dòng)類EurekaServerApplication聲明當(dāng)前應(yīng)用為Eureka服務(wù)使用@EnableEurekaServer
注解
@SpringBootApplication
@EnableEurekaServer
public class springBootEurekaServer {public static void main(String[] args) {SpringApplication.run(springBootEurekaServer.class,args);}
}
4.編寫配置文件application.yml
server:port: 8080
spring:application:name: consumer
# 注冊(cè)中心地址
eureka:client:service-url:defaultZone: http://127.0.0.1:8761/eurekaregistry-fetch-interval-seconds: 30
5.啟動(dòng)EurekaServerApplication
6.測(cè)試訪問地址http://127.0.0.1:8761,如下信息代表訪問成功
4.2 服務(wù)提供者-注冊(cè)到eureka
<properties><spring-cloud.version>2022.0.5</spring-cloud.version><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.2</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.5</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency> </dependencies> <dependencyManagement><dependencies> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency></dependencies> </dependencyManagement>
@SpringBootApplication
@EnableDiscoveryClient
public class springBootProvider {public static void main(String[] args) {SpringApplication.run(springBootProvider.class,args);}
}
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/db2username: rootpassword: 123456 application:name: providerServer mybatis:type-aliases-package: com.home.pojoconfiguration:log-impl: org.apache.ibatis.logging.stdout.StdOutImplserver:port: 8088 #配置eureka注冊(cè)中心的地址 # 注冊(cè)中心地址 eureka:client:service-url:defaultZone: http://127.0.0.1:8761/eureka # 租約續(xù)約間隔時(shí)間,默認(rèn)30秒eureka:instance:lease-renewal-interval-in-seconds: 30
4.3服務(wù)消費(fèi)者-注冊(cè)到eureka
<properties><spring-cloud.version>2022.0.5</spring-cloud.version><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--當(dāng)前的項(xiàng)目,是eureka的客戶端--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>
</dependencies>
<!--SpringCloud,BOM,依賴清單導(dǎo)入,所有依賴管理的坐標(biāo)-->
<dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement>
@SpringBootApplication
@EnableDiscoveryClient
public class springBootConsumerStarter {public static void main(String[] args) {SpringApplication.run(springBootConsumerStarter.class,args);}@Beanpublic RestTemplate restTemplate(){return new RestTemplate();}
}
server:port: 8080 spring:application:name: consumer # 注冊(cè)中心地址 eureka:client:service-url:defaultZone: http://127.0.0.1:8761/eurekaregistry-fetch-interval-seconds: 30
4.4消費(fèi)者通過Eureka訪問提供者
@RestController
@RequestMapping("/a")
public class usersssController {@AutowiredRestTemplate restTemplate;@Autowiredprivate DiscoveryClient discoveryClient;@RequestMapping("/b")public usersss findAll(){
//discoveryClient 可以拉取注冊(cè)中心中服務(wù)列表//getInstances(服務(wù)名),當(dāng)前服務(wù)只有1個(gè),返回值是List集合,獲取0索引服務(wù)對(duì)象ServiceInstance instance = discoveryClient.getInstances("PROVIDERSERVER").get(0);//instance服務(wù)對(duì)象的實(shí)例。獲取服務(wù)提供者的IP,端口號(hào)String host = instance.getHost();int port = instance.getPort();return restTemplate.getForObject("http://"+host+":"+port+"/user/findAll", usersss.class);}
}
# 租約續(xù)約間隔時(shí)間,默認(rèn)30秒
eureka.instance.lease-renewal-interval-in-seconds: 30?
每過30s注冊(cè)中心查看服務(wù)端是否續(xù)租
# 每隔多久獲取服務(wù)中心列表,(只讀備份)
eureka.client.registry-fetch-interval-seconds: 30?
每隔30s客戶端拉去服務(wù)列表
5、SpringCloud Alibaba(Nacos)
5.1?Nacos和Eureka的特點(diǎn)
Eureka的優(yōu)點(diǎn)包括:
1、簡(jiǎn)單易用:Eureka框架非常簡(jiǎn)單易用,便于快速上手和部署。
2、高可用性:Eureka支持多節(jié)點(diǎn)部署,并會(huì)自動(dòng)將失效的節(jié)點(diǎn)剔除,確保整個(gè)系統(tǒng)的高可用性和彈性。
3、動(dòng)態(tài)擴(kuò)展性:Eureka可以根據(jù)實(shí)際需求進(jìn)行擴(kuò)展,通過添加新的服務(wù)提供者可以很容易地增加應(yīng)用程序的處理能力。
4、易于集成:Eureka可以與Spring Cloud等流行的微服務(wù)框架進(jìn)行無(wú)縫集成,從而提供更完善的微服務(wù)體系支持。
Eureka的不足之處:
1、Eureka Server 為單點(diǎn)故障問題,雖然可以通過多節(jié)點(diǎn)部署來(lái)優(yōu)化和緩解,但是在高并發(fā)場(chǎng)景下仍可能成為限制系統(tǒng)擴(kuò)展的瓶頸。
2、Eureka的服務(wù)注冊(cè)中心本身也需要高可用環(huán)境,一旦出現(xiàn)問題,可能影響到整個(gè)微服務(wù)的正常運(yùn)行。
Nacos的優(yōu)點(diǎn)包括:
1、高可用性:Nacos支持多節(jié)點(diǎn)部署,通過選舉算法實(shí)現(xiàn)了高可用和故障轉(zhuǎn)移能力,在節(jié)點(diǎn)宕機(jī)或網(wǎng)絡(luò)異常情況下仍能保證整個(gè)系統(tǒng)的穩(wěn)定運(yùn)行。
2、動(dòng)態(tài)擴(kuò)展性:Nacos可以根據(jù)實(shí)際需求進(jìn)行快速擴(kuò)展和縮容,支持集群、多數(shù)據(jù)中心、地域感知等特性。
3、完備的功能支持:Nacos支持服務(wù)注冊(cè)與發(fā)現(xiàn)、配置管理、流量管理、DNS解析、存儲(chǔ)KV對(duì)等功能,并且提供了Web界面和RESTful API等多種方式來(lái)使用這些功能。
4、易于集成:Nacos提供了多種語(yǔ)言和框架的集成方案,并且支持Spring Cloud等流行的微服務(wù)框架。
總的來(lái)說(shuō),Nacos是一個(gè)功能齊全、易于使用和高可用的分布式服務(wù)治理平臺(tái),可以為分布式系統(tǒng)提供高效、穩(wěn)定的運(yùn)行環(huán)境。
5.2?Nacos消費(fèi)者
使用SpringBoot創(chuàng)建項(xiàng)目,搭建提供者服務(wù)(user-service)和消費(fèi)者服務(wù)(consumer-service)。
創(chuàng)建項(xiàng)目user-service
執(zhí)行創(chuàng)建數(shù)據(jù)庫(kù)表,sql腳本
搭建三層架構(gòu)Mapper、Service、Controller,創(chuàng)建根據(jù)id查詢用戶接口
配置user-service服務(wù)
啟動(dòng)2個(gè)端口9091、9092服務(wù),并測(cè)試服務(wù)user-service
創(chuàng)建項(xiàng)目consumer-service
配置RestTemplate對(duì)象,注入Spring容器
搭建service層和controller層,通過RestTemplate對(duì)象發(fā)送請(qǐng)求訪問提供者接口
測(cè)試消費(fèi)者服務(wù)consumer-service
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>
<!--SpringCloud,BOM,依賴清單導(dǎo)入,所有依賴管理的坐標(biāo)--><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${spring.cloud.alibaba.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>
@RestController
@RequestMapping("user")
public class UserController {@Autowiredprivate UserService userService;@RequestMapping("queryUserById")public User queryUserById(Integer id){return userService.queryUserById(id);}
}
@Service
public class UserServiceImpl implements UserService{@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate DiscoveryClient discoveryClient;@Overridepublic User queryUserById(Integer id) {List<ServiceInstance> instances = discoveryClient.getInstances("provider_user");ServiceInstance serviceInstance = instances.get(0);String url = "http://"+serviceInstance.getHost()+":"+serviceInstance.getPort();System.out.println("url = " + "http://"+url);User user = restTemplate.getForObject(url+"/user/queryUserById?id=" + id, User.class);return user;}
}
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/db2username: rootpassword: 123456application:name: providerNacoscloud:nacos:discovery:server-addr: 127.0.0.1:8848 mybatis:type-aliases-package: com.home.pojoconfiguration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
5.3 Nacos服務(wù)者
<properties><spring-cloud.version>2022.0.5</spring-cloud.version><spring.cloud.alibaba.version>2022.0.0.0</spring.cloud.alibaba.version><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties>
@RestController
@RequestMapping("/a")
public class usersssController {@AutowiredRestTemplate restTemplate;@Autowiredprivate DiscoveryClient discoveryClient;@RequestMapping("/b/{id}")public usersss findAll(@PathVariable("id") Integer id){
//discoveryClient 可以拉取注冊(cè)中心中服務(wù)列表//getInstances(服務(wù)名),當(dāng)前服務(wù)只有1個(gè),返回值是List集合,獲取0索引服務(wù)對(duì)象
// ServiceInstance instance = discoveryClient.getInstances("providerNacos").get(0);//instance服務(wù)對(duì)象的實(shí)例。獲取服務(wù)提供者的IP,端口號(hào)
// String host = instance.getHost();
// int port = instance.getPort();return restTemplate.getForObject("http://providerNacos/user/findAll/"+id, usersss.class);}
}
server:port: 8080 spring:application:name: consumerNacos # 注冊(cè)中心地址cloud:nacos:discovery:server-addr: 127.0.0.1:8848
6.負(fù)載均衡
將任務(wù)均勻分配
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency>
server:
? port: ${port:9091}
構(gòu)建集群
@RestController
@RequestMapping("/user")
public class userController {@Autowiredhome.services.userServices userServices;@Value("${server.port}")private Integer port;@GetMapping("/findAll/{id}")public usersss findall(@PathVariable("id") Integer id){usersss usersss1= userServices.findAll(id);usersss1.setPort(port);return usersss1;}
}
6.1 修改負(fù)責(zé)均衡算法
public class CustomLoadBalancerConfiguration {
? ? @Bean
? ? ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {
? ? ? ? String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
? ? ? ? return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
? ? }
}
?@Configuration
? ? @LoadBalancerClients(value = {
? ? ? ? ? ? @LoadBalancerClient(name = "providerUser" , configuration = CustomLoadBalancerConfiguration.class) ? ? ?// 將負(fù)載均衡算法應(yīng)用到指定的服務(wù)提供方中
? ? })
? ? public class RestTemplateConfiguration {? ? ? ? @Bean
? ? ? ? @LoadBalanced ? ? ? // 讓RestTemplate具有負(fù)載均衡的能力
? ? ? ? public RestTemplate restTemplate() {
? ? ? ? ? ? return new RestTemplate() ;
? ? ? ? }
}
負(fù)載均衡算法可以改變調(diào)用順序;