Spring Cloud

微服务

1.不同的微服务,不要重复开发相同的业务
2.微服务数据独立,不要访问其它微服务的数据库。
3.微服务可以将自己的业务暴露为接口,供其它微服务调用。
image

实现

开发环境

  • 开发工具:IntelliJ IDEA 2023.2.5 Ultimate
  • 开发框架:Spring boot 3.0.9
  • 语言:Java 21
  • 微服务框架:Spring cloud 2022.0.4
  • 数据库:mysql5.7.4
  • 持久层框架:mybatis3.0.3
  • Java增强工具:lombok 1.18.30

构建工程

1. 创建父工程

使用"Spring Initializr"构建Spring boot项目cloud-service。
删除其他不必要的文件,只留"pom.xml"文件。

pom.xml
<?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>3.0.9</version>
        <relativePath/>
    </parent>

    <packaging>pom</packaging>
    <modules>
        <module>user-service</module>
        <module>order-service</module>
        <module>eureka-server</module>
    </modules>

    <groupId>cn.zyz</groupId>
    <artifactId>cloud-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>cloud-service</name>
    <description>cloud-service</description>

    <properties>
        <java.version>21</java.version>
        <spring-cloud.version>2022.0.4</spring-cloud.version>
        <lombok.version>1.18.30</lombok.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>3.0.3</version>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter-test</artifactId>
            <version>3.0.3</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

packaging:表示打包方式为pom
modules:表示包含的子模块
dependencies:父工程中此处的依赖都会被子模块继承
dependencyManagement:表示此处依赖不被子模块继承
groupId:子模块和父工程相同时,子模块中无需指定

2. 用户微服务

用户微服务:user-service
数据库:cloud_user,位于本地
表:tb_user(id int auto_increment primary key,name varchar(20),address varchar(100))

2.1 构建子模块

右击父工程"cloud-service"->"New Module"->"New Module"

2.2 配置

application.yml
server:
  port: 8081

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_user?useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: root
  application:
    name: userservice

2.3 实体类

cn.zyz.user.pojo.User
@Data
public class User {
    private int id;
    private String username;
    private String address;
}

2.4 DAO

cn.zyz.user.mapper.UserMapper
@Mapper
public interface UserMapper {
    @Select("select * from tb_user where id=#{id}")
    public User getUser(int id);
}

2.5 服务类

cn.zyz.user.service.UserService
@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    public User getUser(int id){
        return userMapper.getUser(id);
    }
}

2.6 控制器类

cn.zyz.user.web.UserController
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    @RequestMapping("/{id}")
    public User getUser(@PathVariable int id) {
        User user = userService.getUser(id);
        System.out.println(user);
        return user;
    }
}

3.订单微服务

订单微服务:order-service
数据库:cloud_order,位于虚拟机Centos上
表:tb_order(id int auto_increment primary key,name varchar(50),price decimal(10,2),num int,user_id int)

3.1 构建子模块

右击父工程"cloud-service"->"New Module"->"New Module"

3.2 配置

application.yml
server:
  port: 8091
spring:
  datasource:
    url: jdbc:mysql://10.10.0.100:3306/cloud_order?useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: root
  application:
    name: orderservice

mybatis:
  configuration:
    map-underscore-to-camel-case: true

map-underscore-to-camel-case: true 表示将下划线命名映射为camel命名法
如:字段"user_id"映射到属性"userId"

3.3 实体类

cn.zyz.order.pojo.Order
@Data
public class Order {
    private int id;
    private String name;
    private double price;
    private int num;
    private int userId;
    private User user;
}

3.4 DAO

cn.zyz.order.mapper.OrderMapper
@Mapper
public interface OrderMapper {
    @Select("select * from tb_order where id=#{id}")
    public Order getOrder(int id);
}

3.5 服务类

cn.zyz.order.service.OrderService
@Service
public class OrderService {
    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private RestTemplate restTemplate;
    public Order getOrder(int id){
        Order order = orderMapper.getOrder(id);
        String url = "http://localhost:8081/user/";
        User user = restTemplate.getForObject(url + order.getUserId(), User.class);
        order.setUser(user);
        return order;
    }
}

3.6 控制器类

cn.zyz.order.web.OrderController
@RestController
@RequestMapping("/order")
public class OrderController {
    @Autowired
    private OrderService orderService;
    @RequestMapping("/{id}")
    public Order getOrder(@PathVariable int id){
        return orderService.getOrder(id);
    }
}

4.Eureka

服务端:记住并管理所有的微服务和心跳监控
客户端:
(1)各种服务向eureka注册服务信息
(2)消费者从eureka拉取所需的服务
(3)消费者利用负载均衡算法,从服务列表中挑选一个
(4)远程调用
说明:
消费者如何感知提供者的健康状况?
服务提供者每隔30秒会向Eureka Server发送心跳请求,报告自己的健康状态,eureka会更新记录服务列表信息,心跳不正常的会被剔除,这样消费都就可以拉取到最新的信息。

4.1 搭建Eureka Server

(1)创建子模块"eureka-server",引入依赖

pom.xml ``` org.springframework.cloud spring-cloud-starter-netflix-eureka-server ```

(2)编写启动类,添加@EnableEurekaServer注解

EurekaApplication.java
@EnableEurekaServer
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class EurekaApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class,args);
    }
}

(3)配置

application.yml server: port: 10086 spring: application: name: eurekaserver eureka: client: service-url: defaultZone: http://127.0.0.1:10086/eureka ``` server: port: 10086 spring: application: name: eurekaserver eureka: client: service-url: defaultZone: http://127.0.0.1:10086/eureka ```

(4)启动
启动后,访问"localhost:10086",就可以看到Eureka服务中心的web界面

4.2 服务注册

注册user-service服务
(1)引入eureka-client依赖

pom.xml
<dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>

(2)配置eureka地址

application.yml
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka

模拟多实例部署:
右键"UserApplication"服务->copy configuration->Enviroment VM options->-Dserver.port=8082

4.3 服务发现

在order-service中完成服务拉取
服务拉取是基于服务名称获得服务列表,然后在服务列表中作负载均衡
(1)引入eureka-client依赖
(2)配置eureka地址
(3)给OrderApplication中的RestTemplate作负载均衡注解

OrderApplication.java
@LoadBalanced
    @Bean(name = "restTemplate")
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
(4)用服务者提供者的服务名称作远程调用 修改OrderService代码,使用服务名代替IP

String url = "http://userservice/user/";

5. Nacos

Nacos是Alibaba的产品,现在是Spring Cloud的一个组件。
Nacos致力于帮助您发现、配置和管理微服务。

5.1 安装nacos服务

下载"nacos-server-2.2.3.zip",解压后在命令行终端运行"starup.cmd -m standalone",管理页面的地址:http://localhost:8848

5.2 配置微服务

(1)父工程"cloud-service"引入Spring Cloud Alibaba管理依赖

pom.xml

	<!-- alibaba的管理依赖-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

PS:
Spring boot 3.0.9
Spring Cloud 2022.0.0
Spring Cloud Alibaba 2022.0.0.0.RC1

(2)微服务"user-service"引入nacos客户端依赖

pom.xml

 <!-- nacos客户端依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

PS:删除Eureka客户端依赖

(3)微服务"user-service"配置nacos服务地址

application.yml

spring:
  cloud:
    nacos:
      server-addr: localhost:8848
(4)微服务"order-service"引入nacos客户端依赖

和(2)相同

(5)微服务"order-service"配置nacos服务地址

和(3)相同

(6)启动微服务实例

在nacos管理页面中可以发现微服务

posted @ 2023-11-29 14:57  框框A  阅读(25)  评论(0编辑  收藏  举报