SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)

微服务技术栈导学

微服务技术是分布式架构(把服务做拆分)的一种

而springcloud仅仅是解决了拆分时的微服务治理的问题,其他更复杂的问题并没有给出解决方案

一个完整的微服务技术要包含的不仅仅是springcloud

微服务技术栈

包括什么
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第1张图片
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第2张图片
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第3张图片

认识微服务

(一)服务架构演变

1、单体架构

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第4张图片

2、分布式架构

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第5张图片

3、服务治理

在拆分的过程中也会有一些问题
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第6张图片

4、微服务

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第7张图片

5、总结

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第8张图片

(二)微服务技术对比

1、微服务结构

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第9张图片

2、微服务技术对比

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第10张图片
SpringCloudAlibaba兼容了前面两种

3、企业需求

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第11张图片

(三)SpringCloud

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第12张图片
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第13张图片

服务拆分

(一)案例Demo

1、服务拆分注意事项

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第14张图片

2、导入服务拆分Demo

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第15张图片
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第16张图片
order表user_id虽然和user表进行关联,但是因为是跨database的,因此无法进行关联查询

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第17张图片
项目中所有的微服务:
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第18张图片
以下是两个分别的application.yml

server:
  port: 8080
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
    username: root
    password: root123456
    driver-class-name: com.mysql.jdbc.Driver
mybatis:
  type-aliases-package: cn.itcast.user.pojo
  configuration:
    map-underscore-to-camel-case: true
logging:
  level:
    cn.itcast: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS
server:
  port: 8081
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_user?useSSL=false
    username: root
    password: root123456
    driver-class-name: com.mysql.jdbc.Driver
mybatis:
  type-aliases-package: cn.itcast.user.pojo
  configuration:
    map-underscore-to-camel-case: true
logging:
  level:
    cn.itcast: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS

将两个都启动:
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第19张图片
在浏览器中(下载Chrome插件Json Viewer)
在这里插入图片描述
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第20张图片

(二)服务远程调用

1、根据订单id查询订单功能

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第21张图片

2、远程调用方式分析

那么问题就转变成了:如何在java代码中(像浏览器一样)发起http请求,这样就能实现远程调用了
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第22张图片
Spring提供了一个工具——RestTemplate,用来发http请求
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第23张图片

通过Bean的方式把RestTemplate注册为其中的一个对象,然后将来可以在任何地方注入这个对象来使用

写在哪里呢?Bean的注入只能放在配置类中,而启动类(OrderApplication)(带有@SpringBootApplication)本身也是配置类,所以完全可以在这里写Bean的注入

@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }

    /**
     * 创建RestTemplate并注入Spring容器
     * @return
     */
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

接下来就可以利用它来发http请求了
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第24张图片

修改OrderService

@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;
    
    // 0.注入RestTemplate
    @Autowired
    private RestTemplate restTemplate;

    public Order queryOrderById(Long orderId) {
        // 1.查询订单
        Order order = orderMapper.findById(orderId);
        // 2.利用RestTemplate发送http请求,查询用户
        // 2.1.url路径
        String url = "http://localhost:8081/user/" + order.getUserId();
        // 2.2.发送http请求,实现远程调用(getForObject默认返回json,加上User.class参数g告诉它返回值的类型,自动转化成User对象)
        User user = restTemplate.getForObject(url, User.class);
        // 3.封装user到Order
        order.setUser(user);
        // 4.返回
        return order;
    }
}

然后重启Order服务(User服务就不需要重启了)
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第25张图片

3、总结

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第26张图片

Eureka注册中心

(一)提供者与消费者

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第27张图片

(二)eureka原理分析

1、服务调用出现的问题

在这里插入图片描述

刚才将user-service服务的ip和端口硬编码在代码中的,有一定问题
所以不能用硬编码方式

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第28张图片

2、Eureka的作用

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第29张图片

每一个服务启动时都会把自己的信息注册给eureka

如果某个心脏不跳动了,eureka会将这个从列表中删除
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第30张图片

3、总结

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第31张图片

(三)搭建eureka服务

1、动手实践

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第32张图片

2、搭建EurekaServer

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第33张图片

搭建EurekaServer需要创建一个独立的微服务

starter是springboot中的自动装配,也就是说在这个依赖中已经帮我们把springeureka的所有的配置都做好了,也就是说我们可以零配置直接拿来用了

当然,自动装配是需要有开关的,第二步这个注解就是eurekaserver自动装配的开关

第三步需要编写一些配置信息,端口信息、服务名称、eureka的地址信息

接下来开始写:
1、创建一个新的module
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第34张图片
引入依赖:

<dependencies>
    
    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
    dependency>
dependencies>

注意到我们引入的时候并没有指定版本信息,以前学习springboot时也遇到过这种情况,原因是在我们的父工程中,已经把依赖的版本都管理好了,所以可以进入cloud-demo的父工程的pom文件看,可以看到spring-boot-starter-parent的版本为2.3.9.RELEASE,以及spring-cloud版本和其他,并且有spring-cloud-dependencies依赖库,里面有大量的springcloud的组件及其版本信息,全都定义好了,所以在我们引入springcloud组件时,我们无需指定任何版本信息

2、编写main函数并添加注解
新建cn.itcast.eureka.EurekaApplication类

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

3、编写一个配置文件
resources下新建application.yml

server:
  port: 10086 # 服务端口
spring:
  application:
    name: eurekaserver # eureka的服务名称
eureka:
  client:
    service-url: # eureka的地址信息
      defaultZone: http://127.0.0.1:10086/eureka

注意由于eureka自己也是一个微服务,会将自己也注册到eureka上(这是为了将来eureka集群去用的),所以它也需要一个名字,而且还需要再配一个eureka的地址eureka.client.service-url

也就是说“这里是为了做服务注册才配置这些信息”

然后点击EurekaApplication左边的三角形启动,就可以在下面的服务中看到多出来了EurekaApplication
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第35张图片
点击这个蓝色的端口号,会自动跳转到浏览器

点击10086,就跳转到了eureka的管理界面
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第36张图片

status中的up表示正常状态,down表示挂掉了,up后面的是ip

(四)服务注册

1、注册user-service

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第37张图片
可以看到,除了依赖不一样(刚才时eureka的服务端,现在是eureka的客户端),这个配置和刚才在eureka中做的配置文件长得非常像。为什么?因为eureka启动时会把自己注册到eureka,所以它也需要配服务名称和地址。所以服务名称和地址的配置实际上是服务注册的配置,只要配了它,就可以做注册


<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>

然后配置yml文件

server:
  port: 8081
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_user?useSSL=false
    username: root
    password: root123456
    driver-class-name: com.mysql.jdbc.Driver
  application:
    name: userservice # user服务的服务名称
mybatis:
  type-aliases-package: cn.itcast.user.pojo
  configuration:
    map-underscore-to-camel-case: true
logging:
  level:
    cn.itcast: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS
eureka:
  client:
    service-url: # eureka的地址信息
      defaultZone: http://127.0.0.1:10086/eureka

然后重启UserApplication

接下来把Order服务也注册到Eureka,同上,然后重启
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第38张图片
这里每个服务都只有一个实例,我们可以每个服务启动多个实例

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第39张图片
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第40张图片
(在这里配置端口,是为了覆盖yml文件的端口的)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第41张图片
然后把它也启动,
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第42张图片

(五)服务发现

我们希望orderservice可以基于服务名称拉取到userservice的两个实例信息,然后实现负载均衡

用服务名称代替ip、端口:在eureka中可以看到userservice这个服务名代指的就是这两个端口

要在多个实例中负载均衡,要给之前用到的RestTemplate这个Bean加一个注解@LoadBalanced

都弄完之后,我们把两个UserApplication的都清空,因为我们想知道OrderApplication究竟使用的是哪一个UserApplication,因为在OrderService中url中只是userservice,没有加任何ip地址

(六)总结

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第43张图片

Ribbon负载均衡

(一)负载均衡原理

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第44张图片
直接在浏览器中访问userservice/user/1是无法访问的

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第45张图片

(二)负载均衡策略

IRule接口决定了负载均衡的策略
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第46张图片
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第47张图片
ZoneAvoidanceRule是默认

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第48张图片
注意第一种代码方式是全局的,也就是说我一旦配了上面这种方案,在orderservice中不管你是调用哪一个微服务,都是randomrule;而第二种配置文件方式会先指定服务名称,再指定负载均衡的规则,只针对某个服务而言。

(三)饥饿加载

重启OrderApplication,
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第49张图片
达到了非常恐怖的311毫秒,然后再刷新一次,
SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第50张图片
时长就只有19毫秒了

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第51张图片

创建LoadBalanceClient的过程中还要做服务的拉取,因此时间长

(这个配置是在orderservice的application.yml文件)

server:
  port: 8080
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
    username: root
    password: root123456
    driver-class-name: com.mysql.jdbc.Driver
  application:
    name: orderservice # order服务的服务名称
mybatis:
  type-aliases-package: cn.itcast.user.pojo
  configuration:
    map-underscore-to-camel-case: true
logging:
  level:
    cn.itcast: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS
eureka:
  client:
    service-url: # eureka的地址信息
      defaultZone: http://127.0.0.1:10086/eureka
userservice:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则
ribbon:
  eager-load: 
    enabled: true # 开启饥饿加载
    clients: # 指定饥饿加载的服务名称
      - userservice
      - xxservice

这个ribbon与上面userservice下的ribbon不冲突

(四)总结

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第52张图片

代码

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第53张图片

(一)pom.xml


<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.0modelVersion>

    <groupId>cn.itcast.demogroupId>
    <artifactId>cloud-demoartifactId>
    <version>1.0version>
    <modules>
        <module>user-servicemodule>
        <module>order-servicemodule>
        <module>eureka-servermodule>
    modules>

    <packaging>pompackaging>

    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.3.9.RELEASEversion>
        <relativePath/>
    parent>

    <properties>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
        <java.version>1.8java.version>
        <spring-cloud.version>Hoxton.SR10spring-cloud.version>
        <mysql.version>5.1.47mysql.version>
        <mybatis.version>2.1.1mybatis.version>
    properties>

    <dependencyManagement>
        <dependencies>
            
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-dependenciesartifactId>
                <version>${spring-cloud.version}version>
                <type>pomtype>
                <scope>importscope>
            dependency>
            
            <dependency>
                <groupId>mysqlgroupId>
                <artifactId>mysql-connector-javaartifactId>
                <version>${mysql.version}version>
            dependency>
            
            <dependency>
                <groupId>org.mybatis.spring.bootgroupId>
                <artifactId>mybatis-spring-boot-starterartifactId>
                <version>${mybatis.version}version>
            dependency>
        dependencies>
    dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
        dependency>
    dependencies>
project>

(二)eureka-server

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第54张图片

1、pom.xml


<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>cloud-demoartifactId>
        <groupId>cn.itcast.demogroupId>
        <version>1.0version>
    parent>
    <modelVersion>4.0.0modelVersion>

    <artifactId>eureka-serverartifactId>

    <properties>
        <maven.compiler.source>8maven.compiler.source>
        <maven.compiler.target>8maven.compiler.target>
    properties>

    <dependencies>
        
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
        dependency>
    dependencies>
project>

2、application.yml

server:
  port: 10086 # 服务端口
spring:
  application:
    name: eurekaserver # eureka的服务名称
eureka:
  client:
    service-url: # eureka的地址信息
      defaultZone: http://127.0.0.1:10086/eureka

3、EurekaApplication.java

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

(三)user-service

在这里插入图片描述

1、pom.xml


<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>cloud-demoartifactId>
        <groupId>cn.itcast.demogroupId>
        <version>1.0version>
    parent>
    <modelVersion>4.0.0modelVersion>

    <artifactId>user-serviceartifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
        dependency>
        
        <dependency>
            <groupId>org.mybatis.spring.bootgroupId>
            <artifactId>mybatis-spring-boot-starterartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
        dependency>
    dependencies>
    <build>
        <finalName>appfinalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            plugin>
        plugins>
    build>
project>

2、application.yml

server:
  port: 8081
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_user?useSSL=false
    username: root
    password: root123456
    driver-class-name: com.mysql.jdbc.Driver
  application:
    name: userservice # user服务的服务名称
mybatis:
  type-aliases-package: cn.itcast.user.pojo
  configuration:
    map-underscore-to-camel-case: true
logging:
  level:
    cn.itcast: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS
eureka:
  client:
    service-url: # eureka的地址信息
      defaultZone: http://127.0.0.1:10086/eureka

3、UserApplication.java

@MapperScan("cn.itcast.user.mapper")
@SpringBootApplication
public class UserApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserApplication.class, args);
    }
}

4、UserController.java

@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 路径: /user/110
     *
     * @param id 用户id
     * @return 用户
     */
    @GetMapping("/{id}")
    public User queryById(@PathVariable("id") Long id) {
        return userService.queryById(id);
    }
}

5、UserService.java

@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    public User queryById(Long id) {
        return userMapper.findById(id);
    }
}

6、User.java

@Data
public class User {
    private Long id;
    private String username;
    private String address;
}

7、UserMapper.java(接口)

@Mapper
public interface UserMapper {
    
    @Select("select * from tb_user where id = #{id}")
    User findById(@Param("id") Long id);
}

(四)order-service

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈(Eureka、Ribbon)_第55张图片

1、pom.xml


<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>cloud-demoartifactId>
        <groupId>cn.itcast.demogroupId>
        <version>1.0version>
    parent>
    <modelVersion>4.0.0modelVersion>

    <artifactId>order-serviceartifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
        dependency>
        
        <dependency>
            <groupId>org.mybatis.spring.bootgroupId>
            <artifactId>mybatis-spring-boot-starterartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
        dependency>
    dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            plugin>
        plugins>
    build>
project>

2、application.yml

server:
  port: 8080
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
    username: root
    password: root123456
    driver-class-name: com.mysql.jdbc.Driver
  application:
    name: orderservice # order服务的服务名称
mybatis:
  type-aliases-package: cn.itcast.user.pojo
  configuration:
    map-underscore-to-camel-case: true
logging:
  level:
    cn.itcast: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS
eureka:
  client:
    service-url: # eureka的地址信息
      defaultZone: http://127.0.0.1:10086/eureka
userservice:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则
ribbon:
  eager-load:
    enabled: true # 开启饥饿加载
    clients: # 指定饥饿加载的服务名称
      - userservice

3、OrderApplication.java

@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }

    /**
     * 创建RestTemplate并注入Spring容器
     * @return
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

4、OrderController.java

@RestController
@RequestMapping("order")
public class OrderController {

   @Autowired
   private OrderService orderService;

    @GetMapping("{orderId}")
    public Order queryOrderByUserId(@PathVariable("orderId") Long orderId) {
        // 根据id查询订单并返回
        return orderService.queryOrderById(orderId);
    }
}

5、OrderService.java

@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;

    // 0.注入RestTemplate
    @Autowired
    private RestTemplate restTemplate;

    public Order queryOrderById(Long orderId) {
        // 1.查询订单
        Order order = orderMapper.findById(orderId);
        // 2.利用RestTemplate发送http请求,查询用户
        // 2.1.url路径
        String url = "http://userservice/user/" + order.getUserId();
        // 2.2.发送http请求,实现远程调用(getForObject默认返回json,加上User.class参数自动转化成User对象)
        User user = restTemplate.getForObject(url, User.class);
        // 3.封装user到Order
        order.setUser(user);
        // 4.返回
        return order;
    }
}

6、User.java

@Data
public class User {
    private Long id;
    private String username;
    private String address;
}

7、Order.java

@Data
public class Order {
    private Long id;
    private Long price;
    private String name;
    private Integer num;
    private Long userId;
    private User user;
}

8、OrderMapper.java(接口)

@Mapper
public interface OrderMapper {

    @Select("select * from tb_order where id = #{id}")
    Order findById(Long id);
}

你可能感兴趣的:(微服务,spring,cloud,分布式)