記事ディレクトリ
1.コンセプト
映画販売システムのアーキテクチャは、サービス プロバイダーと消費者を位置づけるために使用されます。
ユーザーが映画チケット購入システムにアクセスすると、最初にアクセスするのはフロントエンド システム「映画マイクロサービス」であり、映画がマイクロサービスが販売しているチケット発券の過程では、事前にユーザーが登録したユーザー情報を取得する必要があり、この際、ユーザーのマイクロサービスのサービスを呼び出してユーザー情報を取得する必要があります。ここで、ムービー マイクロサービスは「サービス コンシューマー」、ユーザー マイクロサービスは「サービス プロバイダー」です。ムービー マイクロサービスはユーザー クエリ サービスを消費する必要があり、ユーザー マイクロサービスはユーザー クエリ サービスを提供します。
「サービス消費者」と「サービスプロバイダー」の定義:
2. サービスプロバイダーを作成する
まず、簡単なサービス プロバイダーのサンプル プロジェクトを作成しましょう。ここでは、Spring の公式 Web サイトが提供する構築ツールを使用して SpringBoot プロジェクトを直接作成します。https://start.spring.io/ を開きます。
ここに必要な情報を入力します。システムは Maven を使用して構築され、プログラミング言語は Java を使用し、SpringBoot は最新の 2.2.0 (SNAPSHOT スナップショット) バージョンを使用します。グループとアーティファクトは次のとおりです。マイクロサービスとして定義 デモ 関連情報: 「com.microserver.cloud」、「microserver-simple-provider-user」。
最後に、Web、jpa、H2 といういくつかの依存関係が必要です。
ここで、web は、Web 開発をサポートするために必要な Spring-web です。jpa は Spring-jpa で、データベースを操作するための永続層フレームワークです。H2 は、構築された H2 データベースです。データベース内で、いくつかのデータを表示するために使用されます。
「プロジェクトの生成」ボタンをクリックして、Spring Boot に基づいてプロジェクトをビルドします。この時点で、Zip 圧縮パッケージが表示され、ダウンロードが完了します。ダウンロードが完了すると、次のファイルが取得されます:
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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.BUILD-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.microserver.cloud</groupId>
<artifactId>microserver-simple-provider-user</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>microserver-simple-provider-user</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</pluginRepository>
</pluginRepositories>
</project>
SpringBoot のバージョンが以前に選択した 2.2.0-SNAPSHOT バージョンであることがわかり、Web、jpa、および H2 の関連依存関係も導入されています。最上位の src の下に、デフォルトの MicroserverSimpleProviderUserApplication.java クラスが生成されます。
package com.microserver.cloud.microserversimpleprovideruser;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MicroserverSimpleProviderUserApplication {
public static void main(String[] args) {
SpringApplication.run(MicroserverSimpleProviderUserApplication.class, args);
}
}
このクラスは、デフォルトのスタートアップ項目をロードし、SpringBoot プロジェクトを開始するために使用されます。
schema.sql にテーブル作成ステートメントを記述します。
DROP TABLE USER IF EXISTS;
CREATE TABLE USER(
id BIGINT generated BY DEFAULT AS identity, -- h2数据库自增主键语法
username VARCHAR(40) COMMENT '账号',
NAME VARCHAR(20) COMMENT '姓名',
age INT(3) COMMENT '年龄',
balance DECIMAL(10,2) COMMENT '余额',
PRIMARY KEY(id)
);
次に、data.sql を作成してテスト データをユーザー テーブルに挿入します。
挿入したデータを data.sql に書き込みます。
INSERT INTO USER(id,username,NAME,age,balance) VALUES(1,'user1','张三',20,100.00);
INSERT INTO USER(id,username,NAME,age,balance) VALUES(2,'user2','李四',21,200.00);
INSERT INTO USER(id,username,NAME,age,balance) VALUES(3,'user3','王五',22,300.00);
INSERT INTO USER(id,username,NAME,age,balance) VALUES(4,'user4','赵六',23,400.00);
データの準備ができたら、src/main/java の com.microserver.cloud.entity パッケージの下に User エンティティ クラスを作成します。
package com.microserver.cloud.entity;
import java.math.BigDecimal;
public class User implements Serializable{
private Long id;
private String username;
private String name;
private Short age;
private BigDecimal balance;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Short getAge() {
return age;
}
public void setAge(Short age) {
this.age = age;
}
public BigDecimal getBalance() {
return balance;
}
public void setBalance(BigDecimal balance) {
this.balance = balance;
}
}
私たちのプロジェクトでは SpringData-JPA を使用しているため、JPA アノテーションを追加する必要があります。
package com.microserver.cloud.entity;
import java.math.BigDecimal;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class User implements Serializable{
@Id //标记为主键
@GeneratedValue(strategy=GenerationType.AUTO) //主键自增
private Long id;
@Column //标记为数据库字段,下同
private String username;
@Column
private String name;
@Column
private Short age;
@Column
private BigDecimal balance;
//Get与Set方法省略
}
次に、DAO レイヤーを記述し、src/main/java の com.microserver.cloud.dao パッケージの下に UserRepository インターフェイスを作成します。
package com.microserver.cloud.dao;
import org.springframework.data.jpa.repository.JpaRepository;
import com.microserver.cloud.entity.User;
@Repository
public interface UserRepository extends JpaRepository<User, Long>{
}
ここでは、メソッド本体に他のメソッド定義を実装する必要はなく、JpaRepository の親インターフェースには、追加、削除、変更、確認のための共通の操作メソッドがすでに定義されています。
package org.springframework.data.jpa.repository;
import java.util.List;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.QueryByExampleExecutor;
@NoRepositoryBean
public abstract interface JpaRepository<T, ID>
extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T>
{
public abstract List<T> findAll();
public abstract List<T> findAll(Sort paramSort);
public abstract List<T> findAllById(Iterable<ID> paramIterable);
public abstract <S extends T> List<S> saveAll(Iterable<S> paramIterable);
public abstract void flush();
public abstract <S extends T> S saveAndFlush(S paramS);
public abstract void deleteInBatch(Iterable<T> paramIterable);
public abstract void deleteAllInBatch();
public abstract T getOne(ID paramID);
public abstract <S extends T> List<S> findAll(Example<S> paramExample);
public abstract <S extends T> List<S> findAll(Example<S> paramExample, Sort paramSort);
}
この例は非常に単純です。ここではサービス層を記述せず、コントローラー層から DAO 層を直接呼び出します。src/main/java の com.microserver.cloud.controller パッケージの下に UserController クラスを作成します。
package com.microserver.cloud.controller;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import com.microserver.cloud.dao.UserRepository;
import com.microserver.cloud.entity.User;
@RestController
public class UserController {
@Autowired
private UserRepository userDao;
@GetMapping("/findById/{id}")
public User findById(@PathVariable Long id){
Optional<User> userOptional = this.userDao.findById(id);
return userOptional.get();
}
}
このうち @RestController は、Controller が REST 形式のサービスを外部に公開することを指定するもので、@Controller と @ResponseBody を組み合わせたアノテーションであり、JSON 形式で REST サービスを提供することを目的としています。
次の設定を application.yml ファイルに追加します。
server:
port: 7900//在application.yml文件中加入以下配置:
spring:
jpa:
generate-ddl: false//为启动时是否生成DDL语句,这里我们已经自己编写好了,所以false不生成;
show-sql: true//为是否打印SQL语句,这里设置为true
hibernate:
ddl-auto: none//为hibernate每次启动时是否自动创建表单(jpa依赖hibernate),这里要求启动时不做DDL的处理,所以设置为none;
datasource:
platform: h2//用于设置数据源使用的数据库类型,这里为H2;
schema: classpath:schema.sql//用于设置数据库启动时的建表语句文件位置
data: classpath:data.sql//用于设置数据库启动时的数据库信息插入语句文件位置
logging:
level:
root: info//用于设置根目录的日志级别
org.hibernate: INFO//用于设置hibernate的日志级别
org.hibernate.type.descripter.sql.BasicBinder: TRACE
org.hibernate.type.descripter.sql.BasicExtractor: TRACE//用于设置hibernate输出SQL语句到日志,与上面的“spring.jpa.show-sql”配合
com.microserver: DEBUG//设置我们自己业务代码的日志级别为DEBUG,用于体现细粒度的日志,方便查找Bug。
ここでは、MicroserverSimpleProviderUserApplication を com.microserver.cloud パッケージに移動する必要があります。つまり、アプリケーションはサブパッケージのアノテーションをスキャンする必要があるため、SpringBoot には慣習的なルールがあり、アプリケーションの起動クラスはビジネス パッケージの先頭: すべての
準備が完了したので、プロジェクトを開始しましょう。MicroserverSimpleProviderUserApplication スタートアップ クラスの main メソッドを実行します。
最後に「MicroserverSimpleProviderUserApplication: Started」という言葉がコンソールに表示されたら、スタートアップは成功です。
ブラウザーで先ほど作成したサービスにアクセスして、ID 1 のユーザー情報を取得します。
2. サービスコンシューマを作成する
サービスプロバイダーのサービスを呼び出すサービスコンシューマーを作成しましょう。「microserver-simple-consumer-movie」という名前の新しいプロジェクト(同じ名前のアーティファクト)をビルドします。これは前の構築方法と同じです(外部依存関係に必要なのは Web のみで、jpa と h2 は必要ありません)。ここでは詳細には触れません。
User クラスは microserver-simple-provider-user と同じで、JPA に関連するすべてのアノテーションを削除します。
package com.microserver.cloud.entity;
import java.io.Serializable;
import java.math.BigDecimal;
public class User implements Serializable{
private Long id;
private String username;
private String name;
private Short age;
private BigDecimal balance;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Short getAge() {
return age;
}
public void setAge(Short age) {
this.age = age;
}
public BigDecimal getBalance() {
return balance;
}
public void setBalance(BigDecimal balance) {
this.balance = balance;
}
}
サービスプロバイダーのサービスを呼び出すために MovieController を作成します。
package com.microserver.cloud.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.microserver.cloud.entity.User;
@RestController
public class MovieController {
@Autowired
private RestTemplate restRemplate;
@GetMapping("/movie/{id}")
public User findUserById(@PathVariable Long id){
return this.restRemplate.getForObject("http://localhost:7900/findById/"+id, User.class);
}
}
ここでは、RestTemplate クラスを使用して Http サービスを呼び出し、getForObject を使用して、要求された HTTP サービスの URL と返されたエンティティ クラス タイプを渡します。
RestTemplate では開発者がそのコンストラクターのパラメーター SimpleClientHttpRequestFactory オブジェクトを構成する必要があるため、ここでは構成なしで @Autowired のみを記述するため、自動的に挿入することはできません。XML で RestTemplate クラスのインジェクション構成を記述するのと同様に、新しい RestTemplateConfig クラスを作成し、構成クラスとして @Configuration を追加します。
package com.microserver.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
/**
* RestTemplate配置
* 这是一种JavaConfig的容器配置,用于spring容器的bean收集与注册,并通过参数传递的方式实现依赖注入。
* "@Configuration"注解标注的配置类,都是spring容器配置类,springboot通过"@EnableAutoConfiguration"
* 注解将所有标注了"@Configuration"注解的配置类,"一股脑儿"全部注入spring容器中。
*
*/
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
return new RestTemplate(factory);//在Spring容器中注入RestTemplate对象
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
//初始化RestTemplate对象需要的Factory工厂类,biang注入到Spring容器中
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(5000);//读取反馈超时时间5000ms
factory.setConnectTimeout(15000);//连接超时时间15000ms
return factory;
}
}
次に、src/main/resource の下に application.yml を作成します。これには、ポート番号の構成のみが必要です。
server:
port: 7901
最後に、MicroserverSimpleConsumerMovieApplication クラスをパッケージの最上位に移動することを忘れないでください。
サービスプロバイダーとサービスコンシューマーを連続して起動し、サービスコンシューマーのムービーリクエストにアクセスし、
userId 1のユーザー情報を取得します。これまでのところ、消費者はサービス プロバイダーが提供するサービス情報を正常に作成し、正常に利用しています。
要約する
Spring Cloud は、典型的なユースケースに対してすぐに使える優れたエクスペリエンスを提供することに重点を置き、他のユースケースをカバーする拡張メカニズムを提供します。
- 分散/バージョン管理された構成
- サービスの登録と検出
- ルーティング
- サービス間コール
- 負荷分散
- ブレーカ
- グローバルロック
- リーダーの選出とクラスターの状態
- 分散メッセージング