認(rèn)識(shí)微服務(wù)
微服務(wù)架構(gòu)演變:
單體架構(gòu):所有功能集中在一個(gè)項(xiàng)目中開發(fā),打成一個(gè)包部署
分布式架構(gòu):就是各功能模塊的代碼不在同一個(gè)項(xiàng)目中寫了,到時(shí)候修改其中一個(gè)過能的代碼,對(duì)另一個(gè)功能完全沒有任何影響(如果在一個(gè)項(xiàng)目中,修改這個(gè)功能的代碼,就得將所有功能代碼給重新編譯)
服務(wù)治理
問題:
服務(wù)拆分力度
服務(wù)集群地址如何維護(hù)
服務(wù)之間如何實(shí)現(xiàn)遠(yuǎn)程 調(diào)用
服務(wù)健康狀態(tài)如何感知
微服務(wù)
良好架構(gòu)設(shè)計(jì)的分布式架構(gòu)方案,微服務(wù)架構(gòu)特征:
單一職責(zé):功能單一
面向服務(wù):對(duì)外暴露接口(讓其他服務(wù)調(diào)用)
自治:團(tuán)隊(duì)獨(dú)立,技術(shù)獨(dú)立,數(shù)據(jù)獨(dú)立,部署獨(dú)立
隔離降級(jí):服務(wù)做好隔離,容器,降級(jí),避免出現(xiàn)級(jí)聯(lián)問題
維護(hù)服務(wù)節(jié)點(diǎn)信息 – 注冊(cè)中心
微服務(wù)配置的修改 – 配置中心
用戶訪問的微服務(wù) – 服務(wù)網(wǎng)關(guān)
微服務(wù)間調(diào)用報(bào)錯(cuò) – 服務(wù)保護(hù)
微服務(wù)入門案例
服務(wù)拆分與遠(yuǎn)程調(diào)用
服務(wù)拆分
拆分原則
這里我總結(jié)了微服務(wù)拆分時(shí)的幾個(gè)原則:
- 不同微服務(wù),不要重復(fù)開發(fā)相同業(yè)務(wù)
- 微服務(wù)數(shù)據(jù)獨(dú)立,不要訪問其它微服務(wù)的數(shù)據(jù)庫
- 微服務(wù)可以將自己的業(yè)務(wù)暴露為接口,供其它微服務(wù)調(diào)用
入門案例
- 創(chuàng)建父項(xiàng)目
- 導(dǎo)入依賴:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.zjh</groupId>
<artifactId>cloud-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>cloud-demo</name>
<description>cloud-demo</description>
<!--父工程-->
<packaging>pom</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<!-- springCloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR10</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- mysql驅(qū)動(dòng) -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
<version>8.0.15</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.5</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
注意:
這里的環(huán)境是jdk8(建議大家和我一樣)
- 創(chuàng)建子項(xiàng)目user-service
- 導(dǎo)入依賴
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.zjh</groupId>
<artifactId>cloud-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.zjh</groupId>
<artifactId>user-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>user-service</name>
<description>user-service</description>
<properties>
<java.version>8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--mybatis-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- 創(chuàng)建實(shí)體類,mapper,service,controller
- 添加mybatis-plus包掃描配置
@SpringBootApplication
@MapperScan("com.zjh.userservice.mapper")
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
- yml配置設(shè)置
server:
port: 8089
spring:
application:
name: userservice
datasource:
url: jdbc:mysql://localhost:3306/cloud?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
username: root
password: 888888
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true
type-aliases-package: com.zjh.order.pojo
- 創(chuàng)建子項(xiàng)目order-service
和user-service一模一樣,唯一的區(qū)別是,需要再order-service中添加user-service的依賴
<dependency>
<groupId>com.zjh</groupId>
<artifactId>user-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
遠(yuǎn)程調(diào)度
遠(yuǎn)程調(diào)用就是在代碼中訪問到另一個(gè)項(xiàng)目的地址,這樣就可以通過url來使用對(duì)方的方法,從而得到對(duì)方的信息
我們這里order中查詢中的user屬性直接查詢時(shí)得不到的,需要通過訪問user的信息,通過user-service中的getById()來得到,所以我們遠(yuǎn)程調(diào)度user-service項(xiàng)目
步驟:
- 在OrderServiceApplication中將RestTemplate添加到bean
@SpringBootApplication
@MapperScan("com.hwadee.order.mapper")
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
- 調(diào)用RestTemplate來實(shí)現(xiàn)遠(yuǎn)程調(diào)度
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private RestTemplate restTemplate;
public Order queryOrderById(Long orderId) {
// 1.查詢訂單
Order order = orderMapper.findById(orderId);
// 2.利用RestTemplate發(fā)起http請(qǐng)求,查詢用戶
// 2.1.url路徑
String url = "http://localhost:8081/user/" + order.getUserId();
// 2.2.發(fā)送http請(qǐng)求,實(shí)現(xiàn)遠(yuǎn)程調(diào)用
User user = restTemplate.getForObject(url, User.class);
// 3.封裝user到Order
order.setUser(user);
// 4.返回
return order;
}
}
支持請(qǐng)求:get,post,
存在問題:
- order-service在發(fā)起遠(yuǎn)程調(diào)用的時(shí)候,該如何得知user-service實(shí)例的ip地址和端口?
- 有多個(gè)user-service實(shí)例地址,order-service調(diào)用時(shí)該如何選擇?
- order-service如何得知某個(gè)user-service實(shí)例是否依然健康,是不是已經(jīng)宕機(jī)?
我們接下來就使用用戶中心來看一看這個(gè)問題
Eureka注冊(cè)中心
介紹
eureka工作流程
調(diào)用者就是服務(wù)消費(fèi)者,被調(diào)用的對(duì)象就是服務(wù)提供者。注冊(cè)中心,就是我們將服務(wù)提供者的路徑給存到注冊(cè)中心中,當(dāng)服務(wù)消費(fèi)者每次調(diào)用對(duì)面的服務(wù),就通過注冊(cè)中心來訪問對(duì)面的服務(wù)
使用步驟
創(chuàng)建注冊(cè)中心項(xiàng)目
- 添加依賴
spring-cloud-starter-netflix-eureka-server
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.hwadee</groupId>
<artifactId>cloud-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>eureka-server</artifactId>
<dependencies>
<!--eureka服務(wù)端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<version>2.2.10.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- 編寫eureka啟動(dòng)類
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
- 編寫服務(wù)配置文件
server:
port: 10086
spring:
application:
name: eureka-server
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
- 啟動(dòng)服務(wù)
啟動(dòng)微服務(wù),然后在瀏覽器訪問:http://127.0.0.1:10086
注冊(cè)服務(wù)
- 在user-service的pom文件中,引入下面的eureka-client依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.2.10.RELEASE</version>
</dependency>
- 修改服務(wù)配置文件,向eureka注冊(cè)服務(wù),并添加名字
server:
port: 8081
spring:
application: # 給服務(wù)起名字
name: user-service
datasource:
url: jdbc:mysql://localhost:3306/hwadee?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
# 向eureka注冊(cè)服務(wù)
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true
type-aliases-package: com.hadee.user.pojo
使用
- 在order-service的pom文件中,引入下面的eureka-client依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.2.10.RELEASE</version>
</dependency>
- 修改服務(wù)配置文件,向eureka注冊(cè)服務(wù),并添加名字
- 添加@LoadBalanced注解
- @LoadBalanced,進(jìn)行輪循(將同一個(gè)名字的服務(wù)進(jìn)行輪詢?cè)L問)
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
- 使用
public Order queryOrderById(Long orderId) {
// 1.查詢訂單
Order order = orderMapper.findById(orderId);
// 2.利用RestTemplate發(fā)起http請(qǐng)求,查詢用戶
// 2.1.url路徑
String url = "http://user-service/user/" + order.getUserId();
// 2.2.發(fā)送http請(qǐng)求,實(shí)現(xiàn)遠(yuǎn)程調(diào)用
User user = restTemplate.getForObject(url, User.class);
// 3.封裝user到Order
order.setUser(user);
// 4.返回
return order;
}
Ribuu負(fù)載均衡
Nacos注冊(cè)中心
nacos介紹和安裝
- 安裝
- 運(yùn)行
打開安裝的nacos文件夾,在bin文件上建立終端頁,輸入以下語句啟動(dòng)
sh startup.sh -m standalone
- 訪問
nacos注冊(cè)中心地址: http://127.0.0.1:8848/nacos/index.html#/login (賬號(hào)密碼都是nacos)
如果讀取不到,可以嘗試將nacos注冊(cè)中心中的內(nèi)容刪除,然后重新運(yùn)行項(xiàng)目
簡單使用
- 引入依賴
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
- 添加配置(user和order的.xml都需要)
spring:
cloud:
nacos:
server-addr: 127.0.0.1:8848
Nacos配置管理
將配置放到nacos中
springboot啟動(dòng)加載配置文件順序
bootstrap.yml
application.properties
application.yml
增加dev,創(chuàng)建開發(fā)環(huán)境
dev – namespace 開發(fā)環(huán)境
public – namespace 生產(chǎn)環(huán)境
文章來源:http://www.zghlxwxcb.cn/news/detail-802074.html
遠(yuǎn)程調(diào)用OpenFeign
- 引入依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.10.RELEASE</version>
</dependency>
- 添加注解@EnableFeignClients
@SpringBootApplication
@MapperScan("com.zjh.orderservice.mapper")
@EnableFeignClients
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
}
- 編寫Feign的接口類
@FeignClient("user-service")
public interface UserClient {
@GetMapping("/user/{id}")
User findById(@PathVariable("id") Long id);
}
- 使用
public Order queryOrderById(Long orderId) {
// 1.查詢訂單
Order order = orderMapper.findById(orderId);
// 2.設(shè)置用戶
// 2.1 查詢用戶
User user = userClient.findById(order.getUserId());
// 2.2 設(shè)置user
order.setUser(user);
// 3.返回
return order;
}
和使用mapper類似,就是調(diào)用接口的方法文章來源地址http://www.zghlxwxcb.cn/news/detail-802074.html
到了這里,關(guān)于微服務(wù)入門 | 項(xiàng)目分割 | 遠(yuǎn)程調(diào)度Feign | 用戶中心erueka 和 nacos的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!