春のクラウド学習
注意事項ソート元B局UPマスター狂神曰く https://www.bilibili.com/video/BV1jJ411S7xr
参考:新人シャオジエジ https://blog.csdn.net/lijie0213/article/details/107914619
参考:ルフィ https:/ /csp1999.blog.csdn.net/article/details/106255122?spm=1001.2014.3001.5502
1。概要
1.1. 前提条件
- Springboot 開発フレームワークの上手な使い方
- Dubbo + Zookeeper 分散基盤を理解する
- コンピューターの構成メモリは 8G 以上です (私のものは 16G)
1.2. 学習目的
- springcloud を使用してマイクロサービス フレームワークを構築する能力
- マイクロサービスについて学ぶ (インタビューの質問)
2. Springcloudプロジェクトの構築
2.1. 概要
- マイクロサービスの一般的な事例として、Dept 部門モジュールを使用し、コンシューマ (Client) がプロバイダ (Server) が提供するサービスを REST 経由で呼び出します。
- Spring、SpringMVC、Mybatis などについてのこれまでの知識を思い出してください。
- Maven のサブパッケージ モジュール アーキテクチャのレビュー
簡単に言えば、親プロジェクトには複数のサブプロジェクトが含まれます。
複数の Module サブモジュールを含む親プロジェクト
初めて 3 つのサブモジュール (Module) を含む MicroServiceCloud 親プロジェクト (Project)
microservicecloud-api [カプセル化された全体的なエンティティ/インターフェイス/パブリック構成など]
microservicecloud-consumer-dept-80 [サービス プロバイダー]
microservicecloud-provider-dept-8001 [サービス コンシューマ]
2.2、springcloud バージョンの選択
メジャーバージョンの説明
スプリングブーツ | スプリングクラウド | 関係 |
---|---|---|
1.2.x | エンジェルバージョン(エンジェル) | SpringBoot1.2xに対応 |
1.3.x | ブリクストン版 (ブリクストン) | SpringBoot1.3xと互換性あり、SpringBoot1.4xとも互換性あり |
1.4.x | カムデン版(カムデン) | SpringBoot1.4xと互換性あり、SpringBoot1.5xとも互換性あり |
1.5.x | ダルストンバージョン(ダルストン) | SpringBoot1.5xと互換性あり、SpringBoot2.0xと互換性なし |
1.5.x | エッジウェア版 (エッジウェア) | SpringBoot1.5xと互換性あり、SpringBoot2.0xと互換性なし |
2.0.x | フィンチリー・バージョン(フィンチリー) | SpringBoot2.0xと互換性あり、SpringBoot1.5xと互換性なし |
2.1.x | グリニッジ版 (グリニッジ) |
実際の開発バージョン関係
スプリングブートスターター親 | 春の雲の依存関係 | ||
---|---|---|---|
バージョンナンバー | 発売日 | バージョンナンバー | 発売日 |
1.5.2.リリース | 2017-03 | ダルストン.RC1 | 2017-x |
1.5.9.リリース | 2017-11 | エッジウェア.リリース | 2017-11 |
1.5.16.リリース | 2018年4月 | エッジウェア.SR5 | 2018-10 |
1.5.20.リリース | 2018-09 | エッジウェア.SR5 | 2018-10 |
2.0.2.リリース | 2018年5月 | Fomchiey.BULD-スナップショット | 2018-x |
2.0.6.リリース | 2018-10 | フォムチー SR2 | 2018-10 |
2.1.4.リリース | 2019年4月 | グリニッジ.SR1 | 2019年3月 |
後の 2 つの開発バージョンを使用することをお勧めします。
2.3. 関連プロジェクトの作成
1. 新しい親プロジェクトを作成する
以下に示すように新しい Maven プロジェクトを作成します
- 次のように作成されました。
src ファイルを削除し、pom ファイルを 1 つだけ残します (親プロジェクトはロジック コンテンツを書き込む必要はありません)。
- pom ファイルの内容:
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 打包方式 pom-->
<packaging>pom</packaging>
<groupId>org.example</groupId>
<artifactId>springCloudStudy</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>springCloud-api</module>
<module>springCloud-provider-dept-8001</module>
<module>springCloud-consumer-dept-80</module>
</modules>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<lombok.version>1.18.16</lombok.version>
<junit.version>4.12</junit.version>
<log4j.version>1.2.17</log4j.version>
</properties>
<!-- 添加详细依赖-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>0.2.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 引入springcloud依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 引入springboot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.4.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!-- 日志相关-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<!-- lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
Maven の多重継承における型とスコープの使用法 (レビュー):
pomファイルの設定
依存関係のタイプが pom であるのはなぜですか?また、デフォルト値は何ですか?
依存関係のタイプはデフォルトで jar になります。つまり、特定の jar パッケージが導入されます。では、なぜまだ pom の種類が存在するのでしょうか? 多くの jar パッケージを導入する必要がある場合、pom.xml が大きくなりすぎます。考えられる解決策の 1 つは、親プロジェクトを定義することですが、親プロジェクトは 1 つだけです。親プロジェクトの pom.xml ファイルが大きすぎることも原因となる可能性があります。現時点では、pom のタイプを導入しました。これは、すべての jar パッケージを pom にパッケージ化でき、その後 pom に依存します。つまり、依存するすべての jar パッケージをダウンロードできます。
スコープ スコープ
- コンパイル: デフォルトのスコープ。このスコープ内の依存関係がコンパイル、操作、テストで有効であることを示します。
- 提供: テストとコンパイルは有効です
- ランタイム: 有効な実行とテスト
- test: テストに有効
- system: 依存関係が当社によって提供され、Maven がウェアハウス内で依存関係を探す必要がないことを示します。
systemPath
使用する場合は、別のラベルと組み合わせて使用する必要があります。このラベルは、システム内の依存関係の場所を絶対パスで示します。
例:
<dependency>
<groupId>sun.jdk</groupId>
<artifactId>tools</artifactId>
<version>1.5.0</version>
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
- import は多重継承の場合に使用されます
プロジェクトの依存関係を継承することにより、親プロジェクトの dependencyMangement で定義された依存関係を使用する必要があることをサブプロジェクトで宣言できます。ただし、各プロジェクトは一意の親プロジェクトのみを宣言できるため、ある時点でプロジェクトの確立が制限されます。
この目的のために、Maven は、依存関係の socpe を import として設定するという方法を提供します。このメソッドは Maven2.0.9 以降のバージョンでのみ有効であることに注意してください。
dependencyManagement でのみ使用できます
親プロジェクトの依存関係:
<project>
...
<groupId>groupA</groupId>
<artifactId>artifactA</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>test</groupId>
<artifactId>A</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>test</groupId>
<artifactId>B</artifactId>
<version>1.1</version>
</dependency>
</dependencies>
</dependencyManagement>
...
</project>
以前の継承メカニズムが使用されている場合、サブプロジェクト artifactB の pom.xml ファイルは次のように定義されます。
<project>
...
<parent>
<groupId>groupA</groupId>
<artifactId>artifactA</artifactId>
<version>1.0</version>
</parent>
<groupId>groupA</groupId>
<artifactId>artifactB</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>test</groupId>
<artifactId>A</artifactId>
</dependency>
<dependency>
<groupId>test</groupId>
<artifactId>D</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
...
</project>
インポート方法
<project>
...
<groupId>groupA</groupId>
<artifactId>artifactB</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>groupA</groupId>
<artifactId>artifactA</artifactId>
<version>1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>test</groupId>
<artifactId>A</artifactId>
</dependency>
<dependency>
<groupId>test</groupId>
<artifactId>D</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
...
</project>
2. エンティティ springcloud-api を作成します
- サービス、パブリック構成などに関与するエンティティをカプセル化します。
- 部門エンティティ クラスを作成します。
package com.lzh.springcloud.dept;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
/**
* 部门信息
*
* @author LZH
* @version 1.0
* @date 2023/04/07 16:44:34
*/
@Data
@Accessors
@NoArgsConstructor
public class Dept {
/**主键*/
private long deptno;
/**部门名称*/
private String dname;
/**存储数据库名称*/
private String db_source;
}
- スクリプトは次のようになります。
DROP TABLE IF EXISTS `dept_test`;
CREATE TABLE `dept_test` (
`deptno` bigint(20) NOT NULL COMMENT '主键',
`dname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '部门名称',
`db_source` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '存储数据库名称',
PRIMARY KEY (`deptno`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '部门数据' ROW_FORMAT = Compact;
-- ----------------------------
-- Records of dept_test
-- ----------------------------
INSERT INTO `dept_test` VALUES (1, '开发部', 'mysql');
INSERT INTO `dept_test` VALUES (2, '研发部', 'mysql');
INSERT INTO `dept_test` VALUES (3, '事业部', 'mysql');
SET FOREIGN_KEY_CHECKS = 1;
3. サービスプロバイダーを作成する
- pom ファイルは次のようになります。
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- <parent>-->
<!-- <artifactId>springCloudStudy</artifactId>-->
<!-- <groupId>org.example</groupId>-->
<!-- <version>1.0-SNAPSHOT</version>-->
<!-- </parent>-->
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>springCloud-provider-dept-8001</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>springCloudStudy</artifactId>
<version>1.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- 引入实体-->
<dependency>
<groupId>org.example</groupId>
<artifactId>springCloud-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
</project>
- 設定ファイル application.yml
server:
port: 8001
mybatis:
# 配置检索的实体的包的前缀
type-aliases-package: com.lzh.springcloud.dept
mapper-locations: classpath:mybatis/mapper/*.xml
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
spring:
application:
# 微服务的唯一标识
name: springcloud-provider-dept
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/springcloud?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowMultiQueries=true
username: root
password: root
-
単一テーブルの不要なビジネス コードを作成する
-
部門コントローラー:
package com.lzh.springcloud.dept.controller;
import com.lzh.springcloud.dept.Dept;
import com.lzh.springcloud.dept.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 描述
*
* @author LZH
* @version 1.0
* @date 2023/04/07 16:51:49
*/
@RestController
@RequestMapping("/dept")
public class DeptController {
@Autowired
private DeptService deptService;
@PostMapping("/add")
public boolean addDept(Dept dept) {
return deptService.addDept(dept);
}
@RequestMapping("/get/{id}")
public Dept queryById(@PathVariable("id") Long id) {
return deptService.queryById(id);
}
@RequestMapping("/list")
public List<Dept> queryAll() {
return deptService.queryAll();
}
}
- 部門サービス:
package com.lzh.springcloud.dept.service;
import com.lzh.springcloud.dept.Dept;
import java.util.List;
/**
* 描述
*
* @author LZH
* @version 1.0
* @date 2023/04/07 16:52:38
*/
public interface DeptService {
/**
* 添加部门
*
* @param dept
* @return
* @author LZH
* @date 2023/4/7 17:34:21
* @version 1.0
*/
boolean addDept(Dept dept);
/**
* 根据id查出一个部门
*
* @param id
* @return
* @author LZH
* @date 2023/4/7 17:34:21
* @version 1.0
*/
Dept queryById(Long id);
/**
* 查询所有部门信息
*
* @return
* @author LZH
* @date 2023/4/7 17:34:21
* @version 1.0
*/
List<Dept> queryAll();
}
- DeptServiceImpl
package com.lzh.springcloud.dept.service.Impl;
import com.lzh.springcloud.dept.Dept;
import com.lzh.springcloud.dept.dao.DeptDao;
import com.lzh.springcloud.dept.service.DeptService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 描述
*
* @author LZH
* @version 1.0
* @date 2023/04/07 16:53:09
*/
@Slf4j
@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptDao deptDao;
@Override
public boolean addDept(Dept dept) {
return deptDao.addDept(dept);
}
@Override
public Dept queryById(Long id) {
return deptDao.queryById(id);
}
@Override
public List<Dept> queryAll() {
return deptDao.queryAll();
}
}
- ダオ部長:
package com.lzh.springcloud.dept.dao;
import com.lzh.springcloud.dept.Dept;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 描述
*
* @author LZH
* @version 1.0
* @date 2023/04/07 16:58:08
*/
@Mapper
public interface DeptDao {
/**
* 添加部门
*
* @param dept
* @return
* @author LZH
* @date 2023/4/7 17:34:21
* @version 1.0
*/
boolean addDept(Dept dept);
/**
* 根据id查出一个部门
*
* @param id
* @return
* @author LZH
* @date 2023/4/7 17:34:21
* @version 1.0
*/
Dept queryById(Long id);
/**
* 查询所有部门信息
*
* @return
* @author LZH
* @date 2023/4/7 17:34:21
* @version 1.0
*/
List<Dept> queryAll();
}
- DeptMapper.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--核心配置文件-->
<mapper namespace="com.lzh.springcloud.dept.dao.DeptDao">
<!--增加一个部门-->
<insert id="addDept" parameterType="com.lzh.springcloud.dept.Dept">
insert into dept_test (dname,db_source) values (#{dname},DATABASE())
</insert>
<!--根据id查询部门信息-->
<select id="queryById" resultType="com.lzh.springcloud.dept.Dept">
select * from dept_test where deptno = #{depono};
</select>
<!--查询所有的部门信息-->
<select id="queryAll" resultType="com.lzh.springcloud.dept.Dept">
select * from dept_test;
</select>
</mapper>
- スタートアップクラス:
package com.lzh.springcloud;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 启动类
*
* @author LZH
* @version 1.0
* @date 2023/04/07 17:44:41
*/
@Slf4j
@SpringBootApplication
public class springcloud_8001 {
public static void main(String[] args) {
SpringApplication.run(springcloud_8001.class);
log.info("启动成功!!");
}
}
- 起動後のテスト:
4. 消費者を次のように書きます。
- pom 依存関係
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- <parent>-->
<!-- <artifactId>springCloudStudy</artifactId>-->
<!-- <groupId>org.example</groupId>-->
<!-- <version>1.0-SNAPSHOT</version>-->
<!-- </parent>-->
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>springCloud-provider-dept-80</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>springCloudStudy</artifactId>
<version>1.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!-- 引入实体-->
<dependency>
<groupId>org.example</groupId>
<artifactId>springCloud-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
- 設定ファイル:
server:
port: 80
mybatis:
# 配置检索的实体的包的前缀
type-aliases-package: com.lzh.springcloud.dept
mapper-locations: classpath:mybatis/mapper/*.xml
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
spring:
application:
# 微服务的唯一标识
name: springcloud-provider-dept
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/springcloud?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowMultiQueries=true
username: root
password: root
- DeptConsumerController:
package com.lzh.springcloud.deptController;
import com.lzh.springcloud.dept.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
/**
* 消费者
*
* @author LZH
* @version 1.0
* @date 2023/04/07 18:06:35
*/
@RestController
public class DeptConsumerController {
@Autowired
private RestTemplate restTemplate;
// 理解:消费者,不该有service层
// RestTemplate.. 里面有方法供我们调用即可,注册到spring中
//(String url,实体, Class<T> responseType)
//提供多种便捷访问远程http服务的方法,简单的Restful服务模板
//声明提供者的localhost路径
private static final String rest_url_prefix = "http://localhost:8001";
//调用8001提供者的控制器=>根据id查询数据
@RequestMapping("/consumer/dept/get/{id}")
public Dept get(@PathVariable("id") Long id){
// restTemplate.注意和提供者的getmapping或postmapping保持一致
return restTemplate.getForObject(rest_url_prefix+"/dept/get/"+id,Dept.class);
}
//调用8001提供者的控制器=>添加方法
@RequestMapping("/consumer/dept/add")
public Boolean add(Dept dept){
// restTemplate.注意和提供者的getmapping或postmapping保持一致
return restTemplate.postForObject(rest_url_prefix+"/dept/add",dept,Boolean.class);
}
//调用8001提供者的控制器=>查询所有
@RequestMapping("/consumer/dept/list")
public List<Dept> queryall(){
// restTemplate.注意和提供者的getmapping或postmapping保持一致
return restTemplate.getForObject(rest_url_prefix+"/dept/list",List.class);
}
}
- 構成:
package com.lzh.springcloud.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* 描述
*
* @author LZH
* @version 1.0
* @date 2023/04/07 18:08:30
*/
@Configuration
public class Config {
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
- スタートアップクラス:
package com.lzh.springcloud;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 描述
*
* @author LZH
* @version 1.0
* @date 2023/04/07 18:14:38
*/
@Slf4j
@SpringBootApplication
public class Springcloud_80 {
public static void main(String[] args) {
SpringApplication.run(Springcloud_80.class);
log.info("启动成功!!");
}
}
- 8001 サービスと 80 サービスを開始し、80 サービスを使用して 8001 サービスを呼び出します
3. エウレカサービス登録センター
3.1 エウレカとは
Netflix は Eureka に関して API 原則に従っており、
Eureka は Netflix のサブモジュールであり、コア モジュールの 1 つです。Eureka は、クラウド ミドルウェア層でサービスの検出とフェイルオーバーを実現するためにサービスを見つけるために使用される REST ベースのサービスです。サービスの登録と検出はマイクロサービスにとって非常に重要です。サービスの登録と検出では、サービス識別子を使用するだけで済みます。サービスから呼び出される設定ファイルを変更せずにサービスにアクセスできる機能で、Zookeeper などの Dubbo の登録センターと似ています。
3.2 原理の理解
エウレカの基本アーキテクチャ
Springcloud は、Netflix によって開発された Eureka モジュールをカプセル化し、サービスの登録と検出を実現します (Zookeeper と比較)。
EurekaはCSのアーキテクチャ設計を採用しており、EurekaServerはサービス登録機能のサーバーであり、サービス登録センターとなります。
システム内の他のマイクロサービスは、Eureka のクライアントを使用して EurekaServer に接続し、ハートビート接続を維持します。このようにして、システム保守者は EurekaServer を使用してシステム内の各マイクロサービスが正常に実行されているかどうかを監視でき、Springcloud の他の一部のモジュール (Zuul など) は EurekaServer を使用してシステム内の他のマイクロサービスを検出し、関連するロジックを実行できます。
Dubbo アーキテクチャとの比較。
Eureka は、Eureka Server と Eureka Client の 2 つのコンポーネントで構成されます。
Eureka Serverはサービス登録機能を提供しており、各ノードの起動後にEurekaServerに登録されるため、Eureka Server内のサービスレジストリにはすべてのクラスサービスノードの情報が保存され、サービスノードの情報はインターフェースで直観的に確認できます。 . .
Eureka Client は、EurekaServer との対話を簡素化する Java クライアントであり、ラウンドロビン ロード アルゴリズムを使用するロード バランサも組み込まれています。アプリケーションの起動後、ハートビートが EurekaServer に送信されます (デフォルトの間隔は 30 秒です)。Eureka Server が複数のハートビート サイクル内にノードのハートビートを受信しない場合、EurekaServer はサービス レジストリからサービス ノードを削除します (デフォルトのサイクルは 90 秒)。
三つの役割
Eureka Server: サービスの登録と検出を提供します。
Service Provider: サービス プロデューサー。サービス コンシューマーが見つけられるように、独自のサービスを Eureka に登録します。 Service Consumer
: サービス コンシューマー。コンシューマー Serve を見つけるために、Eureka から登録済みサービス リストを取得します。
3.3、Eureka サービス登録センターの構成
1. Eureka の依存関係を pom ファイルに導入します。
2.設定ファイルでEureka関連の設定を行う
3. Eureka アノテーションをスタートアップ クラスに追加します。
1. スタートアップクラス:
package com.lzh.springcloud;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
import org.springframework.context.ConfigurableApplicationContext;
/**
* 描述
*
* @author LZH
* @version 1.0
* @date 2023/04/10 11:42:21
*/
@SpringBootApplication
//表示为Eureka的启动类,接受别人注册进来
@EnableEurekaServer
@Slf4j
public class Springcloud_7001 {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(Springcloud_7001.class);
log.info("启动成功!!");
}
}
2. 設定ファイル:
server:
port: 7001
# Eureka配置
eureka:
instance:
# eureka实例名称
hostname: 127.0.0.1
client:
# 表示是否向 Eureka 注册中心注册自己(这个模块本身是服务器,所以不需要)
register-with-eureka: false
# fetch-registry如果为false,则表示自己为注册中心,客户端的化为 ture
fetch-registry: false
# Eureka监控页面~
service-url:
defaultZone: http://${
eureka.instance.hostname}:${
server.port}/eureka/
3.pom ファイル:
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- <parent>-->
<!-- <artifactId>springCloudStudy</artifactId>-->
<!-- <groupId>org.example</groupId>-->
<!-- <version>1.0-SNAPSHOT</version>-->
<!-- </parent>-->
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
<modelVersion>4.0.0</modelVersion>
<artifactId>springCloud-eureka-7001</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<!-- 引入父依赖-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>springCloudStudy</artifactId>
<version>1.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 引入eureka依赖-->
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
4. アクセスは以下の通りです。
Eurekaサービスの利用、登録、情報設定、自己保護メカニズム
5. springCloud-provider-dept-8001 に Eureka 依存関係を追加します。
1.pom ファイル:
<!-- 添加Eureka依赖-->
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
Eureka アノテーションをスタートアップ クラスに追加する
package com.lzh.springcloud;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
* 启动类
*
* @author LZH
* @version 1.0
* @date 2023/04/07 17:44:41
*/
@Slf4j
@SpringBootApplication
//再服务启动后自动注册到Eureka注册中心去
@EnableEurekaClient
public class springcloud_8001 {
public static void main(String[] args) {
SpringApplication.run(springcloud_8001.class);
log.info("启动成功!!");
}
}
Eureka 構成を構成クラスに追加する
eureka:
client:
service-url:
# 访问7001
defaultZone: http://localhost:7001/eureka/
instance:
#修改Eureka中status的默认描述信息。不配置默认为DESKTOP-XXX描述
instance-id: springcloud-provider-dept8001
次のように 8001 サービスと 7001 サービスを開始します。
ステータスの説明は、構成クラスで構成された Eureka のインスタンスのインスタンス ID の内容です。
8001 サービスを停止し、30 秒待つと、保護メカニズムがアクティブになります。
サービスによってロードされる監視情報を構成します。
設定しない場合は 404 になります
pom ファイルに追加します。
<!-- 添加status跳转出页面的详情-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
構成ファイルに以下を追加します。
info:
app.name: com.lzh.springclod
company.name: 苏州xx公司
ステータスの下のルートジャンプをクリックします
次のように:
3.4. EureKa の自己防衛メカニズム: 死ぬよりは生きたほうが良い
一文の要約は次のとおりです。特定のマイクロサービスは、特定の時点で使用できなくなります。eureka はそれをすぐにクリーンアップせず、マイクロサービスの情報を保存します。
デフォルトでは、eureka サーバーは一定期間内にインスタンスのハートビートを受信しない場合、インスタンスをレジストリから削除します (デフォルトは 90 秒)。短期間では、eureka サーバーの自己保護メカニズムがトリガーされます。たとえば、開発およびテスト中にマイクロサービス インスタンスを頻繁に再起動する必要がありますが、eureka サーバーを一緒に再起動することはほとんどありません (eureka 登録センターは変更されないため)開発プロセス中)、1 分以内に閉じられた場合 この保護メカニズムは、受信したハートビートの数が大幅に減少したときにトリガーされます。eureka 管理インターフェースで Renews しきい値と Renews(last min) が確認でき、後者 (過去 1 分間に受信したハートビート数) が前者 (ハートビートしきい値) より小さい場合、保護メカニズムがトリガーされ、赤色の警告が表示されます。 「緊急! EUREKA は、インスタンスが稼働していないにもかかわらず、インスタンスが稼働していると誤って主張している可能性があります。更新はしきい値よりも小さいため、安全のためにインスタンスが期限切れになり始めているわけではありません。警告からわかるように、Eureka は、インスタンスのハートビートは受信できませんが、インスタンスはまだ健全であると考えられ、eureka はこれらのインスタンスを保護し、レジストリから削除しません。
この保護メカニズムの目的は、ネットワーク接続障害を回避することです。ネットワーク障害が発生すると、マイクロサービスと登録センターは正常に通信できなくなりますが、サービス自体は正常であるため、サービスはキャンセルされるべきではありません。eureka が原因でマイクロサービスに障害が発生した場合、ネットワーク障害により誤って削除された場合、ネットワークが復旧しても、マイクロサービスは eureka サーバーに再登録されません。登録要求はマイクロサービスの開始時にのみ開始され、ハートビートとサービス リストの要求のみが登録されるためです。この場合、インスタンスは実行中ですが、他のサービスに認識されることはありません。したがって、eureka サーバーが短期間にあまりにも多くのクライアント ハートビートを失うと、自己保護モードに入ります。このモードでは、eureka はレジストリ内の情報を保護し、マイクロサービスをログアウトしません。障害が回復すると、eureka は自動的に保護モードを終了します。自己保存モードにより、クラスターをより堅牢にすることができます。
ただし、開発とテストの段階では、リリースを頻繁に再起動する必要があります。保護メカニズムがトリガーされても、古いサービス インスタンスは削除されません。この時点で、リクエストは古いインスタンスに送信される可能性があり、インスタンスは削除されています。クローズ済み。これは「リクエストが間違っています」につながり、開発とテストに影響します。したがって、開発およびテスト段階では、自己保存モードをオフにすることができます。eureka サーバー設定ファイルに次の設定を追加するだけです: eureka.server.enable-self-preservation=false【オフにすることはお勧めしません。自己保存メカニズム】
3.5. 登録されたサービスに関する情報を取得する
スタートアップ クラスとクライアント サービスを取得するためのアノテーション
package com.lzh.springcloud;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
* 启动类
*
* @author LZH
* @version 1.0
* @date 2023/04/07 17:44:41
*/
@Slf4j
@SpringBootApplication
//开启Eureka客户端注解,再服务启动后自动注册到Eureka注册中心去
@EnableEurekaClient
//开启服务获取客户端注解,获取一些服务,得到一些信息
@EnableDiscoveryClient
public class springcloud_8001 {
public static void main(String[] args) {
SpringApplication.run(springcloud_8001.class);
log.info("启动成功!!");
}
}
インターフェースからサービス関連情報を取得する
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/get/discoveryInfo")
public Object discoveryInfo(){
List<String> services = discoveryClient.getServices();
List<ServiceInstance> instances = discoveryClient.getInstances("springcloud-provider-dept");
instances.forEach(l->{
System.out.println("主机:"+l.getHost());
System.out.println("主机:"+l.getUri());
System.out.println("主机:"+l.getInstanceId());
System.out.println("主机:"+l.getServiceId());
System.out.println("主机:"+l.getScheme());
});
return services;
}
以下のようにアクセスしてください
3.6. エウレカクラスター構築、とりあえず見てみる
エウレカvs動物園飼育員
- CAP 原則を確認する
RDBMS (MySQL\Oracle\sqlServer) ===> ACID
NoSQL (Redis\MongoDB) ===> CAP
-
アシッドとは何ですか?
A (原子性) 原子性
C (一貫性) 一貫性
I (分離) 分離
D (耐久性) 永続性 -
CAP とは何ですか?
C (一貫性) 強力な一貫性
A (可用性) 可用性
P (パーティション トレランス) パーティション フォールト トレランス
3 つの CAP: CA、AP、CP -
CAP 理論の核心
分散システムが一貫性、可用性、パーティション耐性の 3 つの要件を同時に満たすことは不可能です。CAP 原則
によれば、NoSQL データベースは CA 原則を満たす 3 つのカテゴリに分類されます。 CA
:シングルポイントクラスタ、一貫性と可用性を満たすシステム、通常はスケーラビリティが低い
CP:一貫性と分割耐性を満たすシステム、通常は特に高性能ではない
AP:可用性と可用性を満たすシステムパーティション許容度、通常は一貫性があり、それほど要求が厳しくない -
分散サービス レジストリとして、Eureka が Zookeeper より優れている点は何ですか?
有名な CAP 理論では、分散システムでは C (一貫性)、A (可用性)、P (耐障害性) を同時に満たすことは不可能であると指摘しており、分散システムではパーティション耐障害性 P が保証されなければならないため、 A と C の間でトレードオフができるのは A だけです。
Zookeeper が保証するのは CP —> 一貫性とパーティション耐性を満たすシステム、通常はパフォーマンスが特に高くない
Eureka が保証する AP —> 可用性とパーティション耐性を満たすシステム、通常は一貫性の要件が低い場合がある
Zookeeper は CP を保証
登録センターからサービスリストを照会する場合、登録センターが数分前に登録情報を返しても、サービスを受けることができず、直接シャットダウンして利用できなくなることは許容できます。つまり、サービス登録機能には一貫性よりも使いやすさの要求が高いのです。ただし、Zookeeper ではそのような状況が発生し、マスター ノードがネットワーク障害により他のノードとの接続を失った場合、残りのノードがリーダーを再選出します。問題は、30~120代のリーダーを選出するのに時間がかかりすぎることと、選挙期間中は飼育員クラスター全体が利用できなくなり、選挙期間中の登録サービスの麻痺につながることだ。クラウド展開環境では、ネットワークの問題により、Zookeeper クラスターがマスター ノードを失う可能性が高く、最終的にはサービスを復元できますが、選出に時間がかかるため、長期間登録できなくなり、これは耐えられません。
エウレカはAPを保証
エウレカはそれを理解しているので、使いやすさを優先してデザインしています。Eureka のすべてのノードは同等であり、いくつかのノードに障害が発生しても通常のノードの動作には影響せず、残りのノードは引き続き登録およびクエリ サービスを提供できます。Eureka クライアントが Eureka に登録するとき、接続が失敗したことが判明すると、自動的に他のノードに切り替わります。1 つの Eureka が存在する限り、登録サービスの可用性は維持されますが、見つかった情報は失われる可能性があります。はい、さらに、Eureka には自己保護メカニズムもあります。85% 以上のノードで 15 分以内に正常なハートビートが発生しない場合、Eureka はクライアントとサーバーの間にネットワーク障害があると判断します。登録センター。次の状況:
Eurekaは、長期間ハートビートを受信していないため、有効期限が切れるはずの
サービスを
登録リストから削除していません 安定している場合、現在のインスタンスの新しい登録情報は他のノードに同期されます。
ネットワーク障害により一部のノードが接続を失う状況ですが、動物園の飼育員のように登録サービス全体が麻痺することはありません
4. リボン: 負荷分散 (クライアントに基づく)
4.1 負荷分散とリボン
リボンとは何ですか?
Spring Cloud リボンは、Netflix リボンに基づくクライアント負荷分散ツールのセットです。
簡単に言うと、Ribbon は Netflix がリリースしたオープンソース プロジェクトであり、その主な機能は、クライアント側のソフトウェア負荷分散アルゴリズムを提供し、Netflix の中間層サービスを接続することです。リボンのクライアント コンポーネントは、接続タイムアウト、再試行などの一連の完全な構成項目を提供します。簡単に言えば、以下のすべての LoadBalancer (LB: ロード バランサー) を構成ファイルにリストすることです。リボンは、特定のルール (単純なポーリング、ランダム接続など) に基づいてこれらのマシンを自動的に接続するのに役立ちます。リボンを使用してカスタムの負荷分散アルゴリズムを簡単に実装することもできます。
リボンって何ができるの?
LB (ロード バランサー) は、マイクロサービスまたは分散クラスターでよく使用されるアプリケーションです。
簡単に言うと、負荷分散とは、システムの HA (高利用率) を実現するために、ユーザーのリクエストを複数のサービスに均等に分散することです。
一般的な負荷分散ソフトウェアには、Nginx、Lvs などが含まれます。
Dubbo と SpringCloud は両方とも負荷分散を提供し、SpringCloud の負荷分散アルゴリズムはカスタマイズできます。
ロード バランシングの簡単な分類:
集中型 LB は
、サービス プロバイダーとコンシューマの間で、特定の戦略スクエアを通じてアクセス リクエストをサービス プロバイダーに転送する役割を担う Nginx (リバース プロキシ サーバー) などの独立した LB 機能を使用することを意味します。
プロセスベースの LB は
LB ロジックをコンシューマに統合し、コンシューマはサービス レジストリから利用可能なアドレスを学習し、これらのアドレスから適切なサーバーを選択します。
リボンはインプロセス LB に属しており、コンシューマのプロセスに統合された単なるクラス ライブラリであり、コンシューマはそれを通じてサービス プロバイダーのアドレスを取得します。
4.2. リボンをコンシューマ クライアントに統合する
pom ファイルにリボンの依存関係と Eureka の依存関係を導入する
<!-- 引入Eureka,ribbon可以从Eureka中获取需要拿的服务-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<!-- 引入ribbon-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
Eureka アノテーションをスタートアップ クラスに追加する
//加入Eureka服务
@EnableEurekaClient
構成ファイルで Eureka の依存関係を構成する
# 配置 Eureka
eureka:
client:
service-url:
# 访问路径
defaultZone: http://localhost:7001/eureka/
# 不需要向Eureka中注册自己
register-with-eureka: false
リボンの注釈を構成構成クラスに追加する
package com.lzh.springcloud.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* 描述
*
* @author LZH
* @version 1.0
* @date 2023/04/07 18:08:30
*/
@Configuration
public class Config {
@LoadBalanced //配置负载均衡实现RestTemplate
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
DeptConsumerController でプロバイダーのアクセス パスを変更します。
private static final String rest_url_prefix = "http://SPRINGCLOUD-PROVIDER-DEPT";
8001に続いて8002、8003のプロジェクトを順に作成し、8002、8003に対応するデータベースを作成します
接続方法を変更し、構成ファイル内のサービスの説明を変更し、instance-id 属性を springcloud-provider-dept8003 および 8002 に変更し、dept_test テーブルのデータ ソース名を db02 および db03 に変更します。
プロジェクトを順番に開始する
エウレカサービス登録を見る
リスト インターフェイスにアクセスして、リボンがどのサービスからデータを取得しているかを確認します
更新は次のようになります。
リボンを使用して負荷分散を実現する方法は、次のように実装されています。
4.3. カスタムリボン負荷分散アルゴリズム:
以前は、リボンはポーリング アルゴリズムを使用していましたが、1 つのサービスを 5 回使用した後、次のサービスを使用するアルゴリズムに変更されました。
リボンのランダム アルゴリズム: RandomRule.class ファイル
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.netflix.loadbalancer;
import com.netflix.client.config.IClientConfig;
import edu.umd.cs.findbugs.annotations.SuppressWarnings;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
public class RandomRule extends AbstractLoadBalancerRule {
public RandomRule() {
}
@SuppressWarnings({
"RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE"})
public Server choose(ILoadBalancer lb, Object key) {
if (lb == null) {
return null;
} else {
Server server = null;
while(server == null) {
if (Thread.interrupted()) {
return null;
}
List<Server> upList = lb.getReachableServers();
List<Server> allList = lb.getAllServers();
int serverCount = allList.size();
if (serverCount == 0) {
return null;
}
int index = this.chooseRandomInt(serverCount);
server = (Server)upList.get(index);
if (server == null) {
Thread.yield();
} else {
if (server.isAlive()) {
return server;
}
server = null;
Thread.yield();
}
}
return server;
}
}
protected int chooseRandomInt(int serverCount) {
return ThreadLocalRandom.current().nextInt(serverCount);
}
public Server choose(Object key) {
return this.choose(this.getLoadBalancer(), key);
}
public void initWithNiwsConfig(IClientConfig clientConfig) {
}
}
ホームディレクトリの外に以下のフォルダを作成します。
RuleConfig は次のようになります。
package com.lzh.myrule;
import com.netflix.loadbalancer.IRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 描述
*
* @author LZH
* @version 1.0
* @date 2023/04/12 10:44:11
*/
@Configuration
public class RuleConfig {
@Bean
public IRule myRule(){
return new MyRibbonRule();
}
}
MyRibbonRule コードは次のとおりです。
package com.lzh.myrule;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
/**
* 描述
*
* @author LZH
* @version 1.0
* @date 2023/04/12 10:47:08
*/
public class MyRibbonRule extends AbstractLoadBalancerRule {
int totalCount = 0;
int currentIndex = 0;
@SuppressWarnings({
"RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE"})
public Server choose(ILoadBalancer lb, Object key) {
// 老的版本 RandomRule 采用的是轮询算法,改成新的算法,每个服务依次用5次,然后再调用其他服务
if (lb == null) {
return null;
} else {
Server server = null;
while(server == null) {
if (Thread.interrupted()) {
return null;
}
// 获取active的服务
List<Server> upList = lb.getReachableServers();
// 获取所有的服务
List<Server> allList = lb.getAllServers();
int serverCount = allList.size();
if (serverCount == 0) {
return null;
}
// 新的算法
if (totalCount < 5){
// 每个服务用五次
totalCount++;
server = upList.get(currentIndex);
}else {
// totalCount值大于5次说明,已经进入下一个服务了
totalCount = 0;
currentIndex++;
if (currentIndex>upList.size()) {
currentIndex = 0;
}
server = upList.get(currentIndex);
}
// 老的算法
// int index = this.chooseRandomInt(serverCount);
// server = (Server)upList.get(index);
if (server == null) {
Thread.yield();
} else {
if (server.isAlive()) {
return server;
}
server = null;
Thread.yield();
}
}
return server;
}
}
protected int chooseRandomInt(int serverCount) {
// 获取当前线程的下一个随机整数
return ThreadLocalRandom.current().nextInt(serverCount);
}
@Override
public Server choose(Object key) {
return this.choose(this.getLoadBalancer(), key);
}
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
}
}
スタートアップクラスに追加する
package com.lzh.springcloud;
import com.lzh.myrule.MyRibbonRule;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.RibbonClientName;
/**
* 描述
*
* @author LZH
* @version 1.0
* @date 2023/04/07 18:14:38
*/
@Slf4j
//加入Eureka服务
@EnableEurekaClient
//启用自己创建的ribbon算法规则
@SpringBootApplication
@RibbonClient(name = "SPRINGCLOUD-PROVIDER-DEPT",configuration = MyRibbonRule.class)
public class Springcloud_80 {
public static void main(String[] args) {
SpringApplication.run(Springcloud_80.class);
log.info("启动成功!!");
}
}
スタートアッププロジェクト:
5 回更新して次のサービスに入る
5. Feign: 負荷分散 (サーバーに基づく)
5.1 ふりの概要
Feign は宣言型 Web サービス クライアントであり、コントローラーがサービスを呼び出す方法と同様に、マイクロサービス間の呼び出しを簡単にします。SpringCloud は、Ribbon と Eureka を統合し、Feigin を使用して負荷分散された http クライアントを提供できます
インターフェースを作成して注釈を追加するだけです~
Feign では、主にコミュニティ バージョンで、誰もがインターフェイス指向のプログラミングに慣れています。これは多くの開発者にとって標準です。マイクロサービスを呼び出して 2 つのメソッドにアクセスする
マイクロサービス名 [ribbon]
インターフェイスとアノテーション [feign]
Feign では何ができるでしょうか?
Feign は、Java Http クライアントの作成を容易にすることを目的としています
。リボン + RestTemplate を使用する場合、RestTemplate を使用して Http リクエストをカプセル化し、テンプレート化された呼び出しメソッドのセットを形成します。ただし、実際の開発では、サービスの依存関係への呼び出しが複数ある可能性があるため、インターフェイスが複数の場所から呼び出されることがよくあるため、通常、クライアント クラスはマイクロサービスごとにカプセル化され、これらの依存サービスへの呼び出しをパッケージ化します。したがって、Feign はこれに基づいてさらにカプセル化を行い、依存するサービス インターフェイスの定義と実装を手伝ってくれます。Feign の実装では、インターフェイスを作成し、アノテーションを使用してそれを構成するだけで済みます (以前の Mapper アノテーションと同様に、これにより、Spring Cloud リボンを使用するときにサービス呼び出しクライアントを自動的にカプセル化する開発が簡素化されます。
Feign はデフォルトでリボンを統合します
MicroServiceCloud-Deptのサービスリスト情報を維持するためにRibbonを使用し、ポーリングによりクライアントの負荷分散を実現しますが、Ribbonとは異なり、Feignはサービスバインディングインターフェイスを定義し、宣言型メソッドを使用するだけで済むため、エレガントかつシンプルに実装できます。サービスコール
1. 新しい偽プロジェクトを作成する
2. スタートアップクラスに偽の依存関係を導入する
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- <parent>-->
<!-- <artifactId>springCloudStudy</artifactId>-->
<!-- <groupId>org.example</groupId>-->
<!-- <version>1.0-SNAPSHOT</version>-->
<!-- </parent>-->
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
<modelVersion>4.0.0</modelVersion>
<artifactId>springCloud-consumer-dept-feign-80</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>springCloudStudy</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- 引入实体-->
<dependency>
<groupId>org.example</groupId>
<artifactId>springCloud-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 引入Eureka,ribbon可以从Eureka中获取需要拿的服务-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<!-- 引入ribbon-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<!-- 引入feign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
</dependencies>
</project>
3. 構成クラス
server:
port: 80
mybatis:
# 配置检索的实体的包的前缀
type-aliases-package: com.lzh.springcloud.dept
mapper-locations: classpath:mybatis/mapper/*.xml
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
spring:
application:
# 微服务的唯一标识
name: springcloud-provider-dept
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/springcloud?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowMultiQueries=true
username: root
password: root
# 配置Eureka
eureka:
client:
# 不注册自己
register-with-eureka: false
service-url:
defaultZone: http://localhost:7001/eureka/
4. 消費者サービスへの電話
package com.lzh.springcloud.deptController;
import com.lzh.springcloud.dept.Dept;
import com.lzh.springcloud.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
/**
* 消费者
*
* @author LZH
* @version 1.0
* @date 2023/04/07 18:06:35
*/
@RestController
public class DeptConsumerController {
@Autowired
private DeptService deptClientService;
/**
* 消费方添加部门信息
* @param dept
* @return
*/
@RequestMapping("/consumer/dept/add")
public boolean add(Dept dept) {
return deptClientService.addDept(dept);
}
/**
* 消费方根据id查询部门信息
* @param id
* @return
*/
@RequestMapping("/consumer/dept/get/{id}")
public Dept get(@PathVariable("id") Long id) {
return deptClientService.queryById(id);
}
/**
* 消费方查询部门信息列表
* @return
*/
@RequestMapping("/consumer/dept/list")
public List<Dept> list() {
return deptClientService.queryAll();
}
}
5. スタートアップクラス
package com.lzh.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.ConfigurableApplicationContext;
/**
* 描述
*
* @author LZH
* @version 1.0
* @date 2023/04/15 13:17:21
*/
@SpringBootApplication
@EnableEurekaClient
// feign客户端注解,并指定要扫描的包以及配置接口DeptClientService
@EnableFeignClients(basePackages = {
"com.lzh.springcloud"})
public class springcloud_feign {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(springcloud_feign.class);
System.out.println("feign启动成功!!");
}
}
6. springCloud-apiにfeignが導入され、サービスインターフェースが記述されてから
<!-- 引入feign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
7. 部門インターフェース:
package com.lzh.springcloud.service;
import com.lzh.springcloud.dept.Dept;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import java.util.List;
/**
* dept相关service
*
* @author LZH
* @version 1.0
* @date 2023/04/15 13:34:39
*/
// @FeignClient:微服务客户端注解,value:指定微服务的名字,这样就可以使Feign客户端直接找到对应的微服务
@FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT")
public interface DeptService {
@GetMapping("/dept/get/{id}")
Dept queryById(@PathVariable("id") Long id);
@GetMapping("/dept/list")
List<Dept> queryAll();
@PostMapping("/dept/add")
boolean addDept(Dept dept);
}
8. 順番に開始
9. 正常に取得されました:
6. Hystrix: サービスヒューズ
分散システムが直面する問題
複雑な分散アーキテクチャのアプリケーションには多数の依存関係があり、それぞれの依存関係は必ずいつかは失敗します。
6.1 サービスアバランチ
複数のマイクロサービス間で呼び出しを行う場合、マイクロサービス A がマイクロサービス B とマイクロサービス C を呼び出し、マイクロサービス B とマイクロサービス C が他のマイクロサービスを呼び出すとします。これはいわゆる「ファンアウト」です。リンク上のマイクロサービスが長すぎるか、マイクロサービス A が使用できない場合、マイクロサービス A への呼び出しがますます多くのシステム リソースを占有し、システムのクラッシュ、いわゆる「雪崩効果」が発生します。
高トラフィックのアプリケーションの場合、単一のバックエンド依存関係により、すべてのサーバー上のすべてのリソースが数十秒以内に飽和する可能性があります。障害よりもさらに悪いことに、これらのアプリケーションはサービス間の遅延の増大を引き起こし、バックアップ キュー、スレッド、その他のシステム リソースに負担をかけ、システム全体でさらに連鎖的な障害を引き起こす可能性があります。これらすべては、障害と遅延を監視する必要があることを示しています。単一の依存関係に障害が発生しても、アプリケーション全体やシステムの動作には影響しません。
ハンサムを救うために車を放棄する必要があります!
6.2 ハイストリックスとは何ですか?
Hystrix は、分散システムの遅延とフォールト トレランスに対処するために使用されるオープン ソース ライブラリです。分散システムでは、タイムアウトや例外など、多くの依存関係が必然的に呼び出しに失敗します。Hystrix は、依存関係の場合にそれを保証できます。システム サービス全体の障害が発生することはなく、連鎖的な障害が回避され、分散システムの回復力が向上します。
「サーキット ブレーカー」自体はスイッチング デバイスです。サービス ユニットに障害が発生すると、サーキット ブレーカーの障害監視 (ヒューズ切れと同様) を通じて、予期された処理可能な代替応答 (FallBack) が呼び出し元に返されます。サービス呼び出し側のスレッドが長時間不必要に占有されないようにするため、長時間待機したり、呼び出し側メソッドで処理できない例外をスローしたりすることで、分散システムでの障害の拡大を防ぎます。システム、雪崩さえも。
6.3 ハイストリックスは何ができるのですか?
サービスの低下
サービス回線の切断
サービスのスロットリング
ほぼリアルタイムの監視
...
すべてが正常な場合、リクエスト フローは次のようになります。
多くのバックエンド システムの間に潜在的にブロックしているサービスがある場合、ユーザー リクエスト全体がブロックされる可能性があります。
大量のトラフィックが発生すると、単一のバックエンドの依存関係が数秒以内にすべてのサーバー上のすべてのリソースを飽和させる可能性があります。
ネットワークまたはクライアント ライブラリを介してネットワーク リクエストを行うことができるアプリケーション内のすべてのポイントは、潜在的な障害の原因となります。これらのアプリケーションは、障害が発生するよりもさらに悪いことに、サービス間の待機時間の増加、キュー、スレッド、その他のシステム リソースのバックアップを引き起こし、システム全体でさらに連鎖的な障害を引き起こす可能性があります。
上の図に示されているアーキテクチャは、Hystrix を使用して基礎となる各依存関係をラップすると、下の図のように変化します。各依存関係は互いに分離されており、遅延が発生したときに満たせるリソースが制限されており、依存関係のあらゆる種類の障害に対応して何を行うかを決定するフォールバック ロジックでラップされています。
公式サイト情報:https://github.com/Netflix/Hystrix/wiki
6.4 サービスサーキットブレーカー
サービス ヒューズとは何ですか?
ヒューズ メカニズムは、アバランシェ効果に勝つマイクロサービス リンク保護メカニズムです。
ファンアウト リンクのマイクロサービスが利用できない場合、または応答時間が長すぎる場合、サービスが低下し、ノードのマイクロサービスの呼び出しが中断され、間違った応答情報がすぐに返されます。ノードのマイクロサービス呼び出し応答が正常であることを検出した後、呼び出しリンクが復元されます。SpringCloud フレームワークでは、ヒューズ メカニズムは Hystrix を通じて実装されます。Hystrix はマイクロサービス間の呼び出しのステータスを監視し、失敗した呼び出しが特定のしきい値に達すると、デフォルトでは 5 秒以内に 20 回の呼び出しが失敗し、ヒューズ メカニズムがアクティブになります。ヒューズ メカニズムのアノテーションは @HystrixCommand です。
6.5 サービスサーキットブレーカーは次の問題を解決します。
依存オブジェクトが不安定な場合、高速障害の目的を達成でき、
急速障害の後、依存オブジェクトが特定のアルゴリズムに従って復元されるかどうかを動的にテストできます。
1. springCloud-provider-dept-8001 モジュールをコピーします
2. pom ファイルにサービス融合サービスを追加します
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- <parent>-->
<!-- <artifactId>springCloudStudy</artifactId>-->
<!-- <groupId>org.example</groupId>-->
<!-- <version>1.0-SNAPSHOT</version>-->
<!-- </parent>-->
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
<modelVersion>4.0.0</modelVersion>
<artifactId>springCloud-provider-dept-hystrix-8001</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>springCloudStudy</artifactId>
<version>1.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- 引入实体-->
<dependency>
<groupId>org.example</groupId>
<artifactId>springCloud-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 添加Eureka依赖-->
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<!-- 添加服务熔断依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<!-- 添加status跳转出页面的详情-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.5.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.25</version>
</dependency>
</dependencies>
</project>
3. スタートアップ クラス、サービス ヒューズ アノテーションを追加します。
package springcloud;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
* 启动类
*
* @author LZH
* @version 1.0
* @date 2023/04/07 17:44:41
*/
@Slf4j
@SpringBootApplication
//开启Eureka客户端注解,再服务启动后自动注册到Eureka注册中心去
@EnableEurekaClient
//开启服务获取客户端注解,获取一些服务,得到一些信息
@EnableDiscoveryClient
//开启服务熔断注解
@EnableCircuitBreaker
public class springcloud_hystrix_8001 {
public static void main(String[] args) {
SpringApplication.run(springcloud_hystrix_8001.class);
log.info("启动成功!!");
}
}
4. コントローラーの追加とサービス終了後の関連コンテンツ
package springcloud.dept.controller;
import cn.hutool.core.util.ObjectUtil;
import com.lzh.springcloud.dept.Dept;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springcloud.dept.service.DeptService;
/**
* 描述
*
* @author LZH
* @version 1.0
* @date 2023/04/07 16:51:49
*/
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
@RequestMapping("/dept/get/{id}")
// 添加服务熔断注解
@HystrixCommand(fallbackMethod = "hystrixMethod")
public Dept get(@PathVariable("id") Long id){
Dept dept = deptService.queryById(id);
if (ObjectUtil.isEmpty(dept)){
throw new RuntimeException("此id无法查询到用户信息");
}
return dept;
}
/**
* 服务熔断
*
* @param id
* @return
* @author LZH
* @date 2023/4/17 15:17:48
* @version 1.0
*/
public Dept hystrixMethod(@PathVariable("id") Long id){
return new Dept().setDeptno(id).setDname("服务熔断备选部门名称").setDb_source("服务数据源");
}
}
5. プロジェクトを開始する
存在しないデータにアクセスする:
例外をスローするとサービスが融合した
したがって、マイクロサービスのバックグラウンドでの例外またはエラーによるアプリケーション全体または Web ページ全体のエラー報告を回避するには、ヒューズを使用する必要があります。
6.6. サービスのダウングレード
1. サービスのダウングレードとは何ですか?
サービスの低下とは、実際のビジネス状況やトラフィックに応じて、サーバーへの負荷が急激に増加し、サーバーのリソースを解放してサーバーの正常な動作を確保するために、一部のサービスやページが戦略的に処理されないか、単純な方法で処理されることを指します。コアビジネスや効率的な運営。端的に言えば、優先度の高いサービスにシステム リソースを可能な限り割り当てることです。
リソースには限りがありますが、リクエストには制限がありません。同時実行のピーク時にサービスがダウングレードされない場合、サービス全体のパフォーマンスに確実に影響を及ぼし、深刻な場合にはダウンタイムが発生し、一部の重要なサービスが利用できなくなる可能性があります。したがって、通常、ピーク期間中は、コア機能サービスの可用性を確保するために、一部のサービスをダウングレードする必要があります。たとえば、ダブル 11 イベント中は、Ant Forest の表示や注文履歴の表示など、トランザクションに関係のないすべてのサービスがダウングレードされます。
サービスのダウングレードは主にどのようなシナリオに使用されますか? マイクロサービス アーキテクチャ全体の負荷が事前に設定された上限しきい値を超える場合、または今後のトラフィックが事前に設定されたしきい値を超えることが予想される場合、重要または基本的なサービスを正常に実行できるようにするために、一部の重要でないまたは緊急ではないサービスの使用の遅延または一時停止が行われます。サービスまたはタスクによるサービスの使用。
ダウングレードの方法は、ユーザーへのポイント付与を遅らせるなどサービスを遅らせたり、キャッシュに入れてサービスが安定するのを待って実行したり、途中でサービスを終了したりするなど、業務に合わせて方法を決定できます。関連記事の推奨を閉じるなどの詳細な範囲。
上図からわかるように、サービス A へのアクセス数が一定期間内に急激に増加する一方で、サービス B およびサービス C へのアクセス数が減少した場合、サービス A、B への負担を軽減するために、サービス A、B へのアクセス数が減少します。このとき、C は負荷を負担するために一部のサービス機能を一時的に停止する必要があり、A への負担を分担するために、A のサービスの一部をサービス低下と呼びます。
サービスの低下において考慮すべき質問
1) どのサービスがコア サービスであり、どのサービスが非コア サービスであるか
2) どのサービスが低下をサポートできるか、どのサービスがサポートできないか、低下戦略は何か
3) 他にさらに複雑なビジネスはあるかサービスの低下 シーンを手放すための戦略は何ですか?
自動ダウングレード分類
1) タイムアウトダウングレード: 主にタイムアウト期間、タイムアウトリトライ回数、メカニズムを設定し、応答を検出するために非同期メカニズムを使用します。
2) 失敗数はダウングレードされます: 主に一部の不安定な API に対してです. 失敗した呼び出し数が一定のしきい値に達すると、自動的にダウングレードされます. 応答を検出するために非同期メカニズムを使用することも必要です
3) 障害ダウングレード: たとえば、呼び出されるリモート サービスがハングアップした場合 (ネットワーク障害、DNS 障害、http サービスが不正なステータス コードを返し、rpc サービスが例外をスローした場合)、直接ダウングレードできます。ダウングレードされたソリューションには、デフォルト値 (たとえば、インベントリ サービスがダウンしている場合はデフォルトのスポットに戻ります)、ポケット データ (たとえば、広告がダウンしている場合は、事前に用意されたいくつかの静的ページに戻ります)、キャッシュ (一部のページ) が含まれます。以前に一時的に保存されたキャッシュ データ)
4) 現在の制限のダウングレード: 一部の制限された製品をフラッシュキルまたはスナップアップする場合、この時点でトラフィックが多すぎるためにシステムがクラッシュする可能性があります。このとき、トラフィックを制限するためにトラフィック制限が使用されます。トラフィック制限のしきい値が設定されている場合、に達すると、後続のリクエストはダウングレードされます。ダウングレード後の解決策は次のとおりです: キュー ページ (ユーザーをキュー ページに誘導し、後で再試行)、在庫切れ (ユーザーに在庫切れを直接通知)、エラー ページ (イベントは人気すぎます。しばらくお待ちください) 再試行してください)。
2. 簡単な実装
springCloud-api のサービスに実装クラスを追加します
package com.lzh.springcloud.service;
import com.lzh.springcloud.dept.Dept;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 服务熔断内容
*
* @author LZH
* @version 1.0
* @date 2023/04/18 13:49:53
*/
@Component
public class DeptCilentServiceFallBackFactory implements FallbackFactory {
@Override
public DeptService create(Throwable throwable) {
return new DeptService(){
@Override
public Dept queryById(Long id) {
return new Dept().setDeptno(id).setDname("降级了,没有数据了").setDb_source("降级啦");
}
@Override
public List<Dept> queryAll() {
return null;
}
@Override
public boolean addDept(Dept dept) {
return false;
}
};
}
}
DeptService にサービスのダウングレード メソッドを追加
package com.lzh.springcloud.service;
import com.lzh.springcloud.dept.Dept;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import java.util.List;
/**
* dept相关service
*
* @author LZH
* @version 1.0
* @date 2023/04/15 13:34:39
*/
// @FeignClient:微服务客户端注解,value:指定微服务的名字,这样就可以使Feign客户端直接找到对应的微服务
@FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT",fallbackFactory = DeptCilentServiceFallBackFactory.class)
public interface DeptService {
@GetMapping("/dept/get/{id}")
Dept queryById(@PathVariable("id") Long id);
@GetMapping("/dept/list")
List<Dept> queryAll();
@PostMapping("/dept/add")
boolean addDept(Dept dept);
}
springCloud-consumer-dept-feign-80 コンシューマ側でサービスのダウングレードを有効にする
server:
port: 80
mybatis:
# 配置检索的实体的包的前缀
type-aliases-package: com.lzh.springcloud.dept
mapper-locations: classpath:mybatis/mapper/*.xml
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
spring:
application:
# 微服务的唯一标识
name: springcloud-provider-dept
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/springcloud?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowMultiQueries=true
username: root
password: root
# 配置Eureka
eureka:
client:
# 不注册自己
register-with-eureka: false
service-url:
defaultZone: http://localhost:7001/eureka/
#开启服务降级
feign:
hystrix:
enabled: true
6.7 サービスヒューズとダウングレードの違い
サービスの融合 —> サーバー: サービスのタイムアウトまたは異常により、融合 (自己融合)サービスの低下と同様の融合~が発生します。 —> クライアント: Web サイト全体のリクエストの負荷を考慮して、サービスが融合またはシャットダウンしている場合、サービスはこのときクライアント側ではFallBackFactoryを用意してデフォルト値(デフォルト値)を返すことができます。全体的なサービスの低下にはつながりますが、それでも使用できるので、直接電話を切るよりは良いでしょう。
トリガーの理由は異なります。サービスの融合は一般にサービス (ダウンストリーム サービス) の障害によって引き起こされ、サービスの低下は一般に全体の負荷から考慮されます。管理目標のレベルが異なります。融合は実際にはフレームワーク レベルのプロセスです。各マイクロすべてのサービスが必要であり (階層なし)、ダウングレードは通常、ビジネスに対して階層的である必要があります (たとえば、ダウングレードは通常、最も周辺のサービスから開始されます)。実装方法は異なり、サービスのダウングレードはコード侵入型です
(コントローラ/または自動ダウングレード)、融着は一般に自己融着と呼ばれます。
ヒューズ、ダウングレード、電流制限:
現在の制限: 同時リクエストのアクセス量を制限します。しきい値を超えると拒否されます。
低下: サービスを優先し、非コア サービス (利用不可) を犠牲にし、コア サービスの安定性を確保します。全体の負荷を考慮します。
ヒューズ: 依存するダウンストリーム サービスに障害が発生すると、システムのクラッシュを回避するためにヒューズがトリガーされ、システムは自動的に実行して回復します。
6.8 ダッシュボードのフロー監視
新しい springcloud-consumer-hystrix-dashboard モジュールを作成する
ダッシュボードの依存関係を pom ファイルに追加する
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- <parent>-->
<!-- <artifactId>springCloudStudy</artifactId>-->
<!-- <groupId>org.example</groupId>-->
<!-- <version>1.0-SNAPSHOT</version>-->
<!-- </parent>-->
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
<modelVersion>4.0.0</modelVersion>
<artifactId>springCloud-consumer-dept-hystrix-dashbord</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>springCloudStudy</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<!--dashboard流监控-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<!-- 引入实体-->
<dependency>
<groupId>org.example</groupId>
<artifactId>springCloud-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 引入Eureka,ribbon可以从Eureka中获取需要拿的服务-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<!-- 引入ribbon-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
</dependencies>
</project>
設定ファイル:
server:
port: 9001
スタートアップクラス:
package com.lzh.springcloud;
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
/**
* 描述
*
* @author LZH
* @version 1.0
* @date 2023/04/18 17:17:37
*/
@SpringBootApplication
//开启dashboard监控
@EnableHystrixDashboard
public class dept_hystrix_dashbord {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(dept_hystrix_dashbord.class);
System.out.println("启动成功!!");
}
}
springCloud-provider-dept-hystrix-8001 スタートアップ クラスが追加されました
package springcloud;
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
/**
* 启动类
*
* @author LZH
* @version 1.0
* @date 2023/04/07 17:44:41
*/
@Slf4j
@SpringBootApplication
//开启Eureka客户端注解,再服务启动后自动注册到Eureka注册中心去
@EnableEurekaClient
//开启服务获取客户端注解,获取一些服务,得到一些信息
@EnableDiscoveryClient
//开启服务熔断注解
@EnableCircuitBreaker
public class springcloud_hystrix_8001 {
public static void main(String[] args) {
SpringApplication.run(springcloud_hystrix_8001.class);
log.info("启动成功!!");
}
//增加一个 Servlet
@Bean
public ServletRegistrationBean hystrixMetricsStreamServlet(){
ServletRegistrationBean registrationBean = new ServletRegistrationBean(new HystrixMetricsStreamServlet());
//访问该页面就是监控页面
registrationBean.addUrlMappings("/actuator/hystrix.stream");
return registrationBean;
}
}
http://localhost:9001/hystrix にアクセスし、関連する監視サービスを入力します。
サービスを呼び出すと、リアルタイムの監視が表示されます
7. Zuulルーティングゲートウェイ
7.1、ズールとは
Zuul には、リクエストのルーティングとフィルタリングという 2 つの主な機能が含まれています。
ルーティング機能は、外部アクセスのための統一された入り口を実現するための基礎となる、外部リクエストを特定のマイクロサービス インスタンスに転送する役割を担い、フィルタ機能はリクエスト処理の介入を担当します。処理プロセスは、リクエストの検証やサービスの集約などの機能を実装するための基礎となります。ZuulとEurekaは統合されており、Zuu自体はEurekaサービス管理下のアプリケーションとして登録されると同時に、他のマイクロサービスニュースはEurekaから取得、つまり今後のマイクロサービスへのアクセスはZuulを飛び越えて取得されます。
注: Zuul サービスは最終的に Eureka に登録される予定です
プロキシ+ルーティング+フィルタリングの3大機能を提供
7.2 Zuulができること
ルーティング
フィルターの
公式 Web サイトのドキュメント => https://github.com/Netflix/zuul
7.3. Zuulを構築する理由
Netflix.API トラフィックの量と多様性により、制作上の問題が警告なしにすぐに発生することがあります。
このような状況に応じて行動を迅速に変更できるシステムが必要です。
Zuul ではさまざまな種類のフィルターを使用しているため、エッジ サービスに機能を迅速かつ柔軟に適用できます。これらのフィルターは、
次の機能の実行に役立ちます。
認証とセキュリティは、各リソースの認証要件を特定し、要件を満たさないリクエストを拒否します。
洞察とモニタリング エッジで意味のあるデータと統計を生成し、生産の正確な状況を把握します。
動的ルーティングは、必要に応じてリクエストをさまざまなバックエンド クラスターに動的にルーティングします。
ストレス テストでは、クラスターへのトラフィックを徐々に増加させてパフォーマンスを評価します。
負荷制限 - リクエストの種類ごとに割り当てられた容量を減らし、制限を超えるリクエストをドロップします。
静的応答処理 - いくつかの応答をエッジで直接構築します。内部クラスターに転送する代わりに、
マルチリージョンのエラスティックなリクエストを AWS リージョン間でルーティングすることで、ELB の使用を多様化し、当社の強みをメンバーに近づけます。 詳細については、「Netfio で Zuul を使用する方法」を参照してください。
7.4. Zuul コンポーネント
zuul-core – zuul core ライブラリ (フィルターのコンパイルと実行のコア機能が含まれています) zuul
-simple-webapp – zuul Web アプリケーションの例 (zuul-core を使用してアプリケーションを構築する方法を示します)
zuul-netflix – lib パッケージ (他の NetflixOSS を統合します)コンポーネント Zuul に追加します。たとえば、機能領域を使用してルーティング リクエストの処理
zuul-netflix-webapp-webapp を入力します。これにより、zuul-core と zuul-netflix が単純な Webapp プロジェクト パッケージにカプセル化されます。
7.5. Zuulルーティングゲートウェイプロジェクトの構築
Maven プロジェクトを作成します springcloud/springcloud-zuul-9527
springcloud-consumer-hystrix-dashboard プロジェクトのすべての依存関係をインポートし、Zuul の依存関係を追加して
サブプロジェクトを作成します。
設定ファイル
server:
port: 9527
spring:
application:
# 服务名称
name: springcloud-zuul
#Eureka注册
eureka:
client:
service-url:
# 访问7001
defaultZone: http://localhost:7001/eureka/
instance:
#修改Eureka中status的默认描述信息。不配置默认为DESKTOP-XXX描述
instance-id: springcloud-zuul
prefer-ip-address: true
info:
app.name: com.lzh.springclod
company.name: 苏州xx公司
zuul:
routes:
mydept.serviceId: springcloud-provider-dept
#之前的查询链接地址 http://activate.navicat.com:9527/springcloud-provider-dept/dept/get/1
#现在的查询链接地址,配置后为 http://activate.navicat.com:9527/mydept/dept/get/1
#两者都皆可访问(原路径+现配路径)。配置自定义的前缀后 可不让客户端知道真实的ip地址
mydept.path: /mydept/**
#加上此配置后 原路径不能访问(springcloud-provider-dept/dept/get/6),只能通过自定义的规则路径访问。
#ignored-services: springcloud-provider-dept
#星号(*) 隐藏全部的项目真实名字
ignored-services: "*"
prefix: /lzh #设置公共的地址前缀 配置后链接为:activate.navicat.com:9527/li/mydept/dept/get/11
pomファイル
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- <parent>-->
<!-- <artifactId>springCloudStudy</artifactId>-->
<!-- <groupId>org.example</groupId>-->
<!-- <version>1.0-SNAPSHOT</version>-->
<!-- </parent>-->
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
<modelVersion>4.0.0</modelVersion>
<artifactId>springCloud-zuul</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>springCloudStudy</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- 引入zuul网关-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<!-- 引入Eureka注册中心-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<!-- 引入feign负载均衡-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<!-- 引入Hystrix服务熔断-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<!-- 引入ribbon客户端的负载均衡-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<!-- 引入实体类-->
<dependency>
<groupId>org.example</groupId>
<artifactId>springCloud-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- web启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
スタートアップクラス:
package com.lzh.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.ConfigurableApplicationContext;
/**
* 网关启动类
*
* @author LZH
* @version 1.0
* @date 2023/04/20 16:25:45
*/
@SpringBootApplication
@EnableZuulProxy // 开启Zuul
public class Springcloud_zuul {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(Springcloud_zuul.class);
System.out.println("启动成功!!!");
}
}
テスト用にサービスを開始する
C:\Windows\System32\drivers\etc\hosts を表示して、zuul ゲートウェイをシミュレートします
127.0.0.1 activate.navicat.com
zuulを設定する前のアクセスは次のとおりです。
zuul 構成を追加した後のアクセスは次のようになります。
マイクロサービス名が置き換えられて非表示になり、カスタム マイクロサービス名 mydept に置き換えられ、同時にプレフィックス haust が追加され、ルーティング ファンへのアクセスが暗号化されていることがわかります。
詳細については、springcloud 中国語コミュニティの zuul コンポーネントを参照してください: https://www.springcloud.cc/spring-cloud-greenwich.html#_router_and_filter_zuul
8. Spring Cloud Configの分散構成
ダルストン.リリース
Spring Cloud Config は、分散システムの外部構成に対するサーバーとクライアントのサポートを提供します。Config Server を使用すると、すべての環境でアプリケーションの外部プロパティを管理できます。クライアントとサーバー上の概念的なマッピングは Spring 環境および PropertySource の抽象化と同じであるため、Spring アプリケーションによく適合しますが、任意の言語で実行される任意のアプリケーションで使用できます。アプリケーションがデプロイメント プロセスを通じて開発者からテスト、本番環境に移行するときに、これらの環境間の構成を管理し、アプリケーションが移行時に実行するために必要なものがすべて揃っていることを確認できます。サーバーのストレージ バックエンドのデフォルト実装では git が使用されるため、構成環境のタグ付きバージョンや、コンテンツを管理するためのさまざまなツールへのアクセスが簡単にサポートされます。Spring 構成を使用すると、代替実装を追加してプラグインするのが簡単です。
概要
分散システムが直面する – 構成ファイルの問題
マイクロサービスとは、単一のアプリケーション内のビジネスをサブサービスに分割することを意味します。各サービスの粒度は比較的小さいため、システム内には多数のサービスが存在します。各サービスは実行に必要な構成情報を必要とするため、一元化されたサービスになります。 、動的構成管理機能は不可欠です。Spring クラウドは、この問題を解決するために configServer を提供します。各マイクロサービスには application.yml が含まれています。何百もの構成ファイルを変更するのは頭の痛い問題です。
SpringCloud config 分散構成センターとは何ですか?
[外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-pE2ByaTt-1683193762693)(\49.png)]
Spring Cloud Config は、マイクロサービス アーキテクチャ内のマイクロサービスに対する一元的な外部サポートを提供し、構成サーバーは、さまざまなマイクロサービス アプリケーションのすべてのリンクに対して一元的な外部構成を提供します。
Spring Cloud Config は、サーバーとクライアントの 2 つの部分に分かれています。
分散構成センターとも呼ばれるサーバーは、構成サーバーに接続し、クライアントが構成情報を取得し、情報を暗号化および復号化するためのアクセス インターフェイスを提供するために使用される独立したマイクロサービス アプリケーションです。
クライアントは、指定された構成センターを通じてアプリケーション リソースとビジネス関連の構成コンテンツを管理し、起動時に構成センターから構成情報を取得してロードします。デフォルトでは、構成サーバーは git を使用して構成情報を保管します。これは、環境構成のバージョン管理に役立ちます。また、構成コンテンツは、git クライアント ツールを通じて簡単に管理およびアクセスできます。
Spring Cloud Config 分散構成センターでは何ができますか?
構成ファイルの一元管理
異なる環境、異なる構成、動的な構成更新、および /dev /test /prod /beta /release などの異なる環境でのデプロイメント 動作中に構成を動的に調整するため、各サービス
デプロイメント マシンに構成を書き込む必要がなくなりましたファイルを作成すると、サービスは構成センターから独自の情報を取得して構成します。
構成が変更されると、サービスは構成の変更を感知し、再起動せずに新しい構成を適用できます。
構成情報をREST インターフェイスの形式で
Spring Cloudに公開します。 .config 分散構成センターと GitHub の統合
Spring Cloud config では、デフォルトで設定ファイルの保存に git が使用されます (自立型 SVN やローカル ファイルなど、他の方法もあります) が、git が最も推奨されており、http / https アクセスの形式を使用します。
springcloud config 環境のビルド構成
登録コード クラウド アカウント https://gitee.com/。qq wechat経由でログインできます
新しいウェアハウス springcloud-config を作成し、public に設定し、言語とテンプレートとして java を選択します。オープン ソース ライセンス GPL-3.0、ウェアハウスの作成後に現在のウェアハウスの SSH トンネル アドレスをコピーします
コンピューター上に新しいフォルダーを作成し、GitBash ツールを使用して git clone springcloud-config によってコピーされた SSH アドレスを実行し、ウェアハウスの内容をプルします。プルした後、「はい」を選択します。権限が存在しないため、構成する必要があります。現在の Git
Git Daquan[https://gitee.com/all-about-git]
1. 最初のステップは、git 上にウェアハウスを作成することです
2. 倉庫情報を取得する
共通コマンド
# 显示当前的Git配置
$ git config --list
# 编辑Git配置文件
$ git config -e [--global]
# 设置提交代码时的用户信息
$ git config [--global] user.name "[name]"
$ git config [--global] user.email "[email address]"
# 下载一个项目和它的整个代码历史
$ git clone [url]
プルコード
この時点でリモートコードは取得済みです
application.ynl ファイルを作成し、ウェアハウスにプッシュします。
spring:
profiles:
active: dev
---
spring:
profiles: dev
application:
name: springcloud-config-dev
---
spring:
profiles: test
application:
name: springcloud-config-test
正常に送信されました:
はじめに ケーススタディ
新しいサブプロジェクトを作成します。
pom ファイルは次のようになります。
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- <parent>-->
<!-- <artifactId>springCloudStudy</artifactId>-->
<!-- <groupId>org.example</groupId>-->
<!-- <version>1.0-SNAPSHOT</version>-->
<!-- </parent>-->
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
<modelVersion>4.0.0</modelVersion>
<artifactId>springCloud-config-server-2233</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>springCloudStudy</artifactId>
<version>1.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- 引入springboot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
<!-- 监控可不加-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
</project>
クラスを開始し、サービス構成のアノテーションを開きます
package com.lzh.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
/**
* 启动类
*
* @author LZH
* @version 1.0
* @date 2023/04/24 14:39:34
*/
@SpringBootApplication
//开启配置服务
@EnableConfigServer
public class springcloud_2233 {
public static void main(String[] args) {
SpringApplication.run(springcloud_2233.class);
System.out.println("启动成功!!");
}
}
設定ファイル
server:
port: 2233
spring:
application:
name: springcloud-config-server
cloud:
config:
server:
git:
uri: https://gitee.com/xxx/lzh_springcloud.git
#不加报错 Authentication is required but no CredentialsProvider has been registered
username: xxx
password: xxx
プライベート接続にはユーザー名とパスワードが必要です
エラー:
認証が必要ですが、CredentialsProvider が登録されていません
以下のようにアクセスしてください
http://localhost:2233/application-dev.yml
http://localhost:2233/application-test.yml
config-cilent.yml 構成ファイルをウェアハウスに追加します。
内容は以下の通りです。
#启动环境选择的配置
spring:
profiles:
active: dev
#springboot启动多环境的配置
---
server:
port: 8201
#spring的配置
spring:
profiles: dev
application:
name: springcloud-config-client-dev
#Eureka的配置。 服务注册到Eureka中,需要一个路径地址
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
---
server:
port: 8202
#spring的配置
spring:
profiles: test
application:
name: springcloud-config-client-test
#Eureka的配置。 服务注册到Eureka中,需要一个路径地址
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
ファイルをリモートウェアハウスにプッシュします
git コマンドは次のとおりです。
GitBash打开命令工具
cd 至 springcloud-config
git add . 将文件添加到暂存区
git status 查看状态
git commit -m “一次提交” 本地提交,-m为提交时写的信息
git push origin master 提交到远程的当前路径分枝