美文网首页
spring cloud 入门学习【结合实例】——开发工具为id

spring cloud 入门学习【结合实例】——开发工具为id

作者: 第一千零一名_5a5d | 来源:发表于2020-08-03 19:30 被阅读0次

一、Spring cloud 相关组件停更及替换方案(看图)

image.png

二、说明

本文章使用的cloud组件:

  • eureka
  • ribbon
  • openfeign

三、版本说明

spring boot 与 cloud 版本对应关系:

Springboot-cloud版本对应关系.jpeg

根据官网推荐,本文使用spring boot 2.2.2 + spring cloud Hoxton.SR1
当前最佳:spring boot 2.3.1.RELEASE + spring cloud Hoxton.SR6

其它:

jdk1.8, maven 3.6.3

四、开始工程

工程介绍:
订单模块——>eureka(高可用)——>(负载均衡)支付模块
修改hosts文件:
添加一行:

127.0.0.1  localhost2

1、工程目录

工程目录.png

2、父工程

使用idea创建新工程

使用maven工具创建-选择jdk1.8-修改项目名、groupid


创建父工程.png

修改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>

    <groupId>org.learning.springcloud</groupId>
    <artifactId>new-cloud</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>pom</packaging>

    <name>Maven</name>
    <!-- FIXME change it to the project's website -->
    <url>http://maven.apache.org/</url>
    <inceptionYear>2001</inceptionYear>

    <distributionManagement>
        <site>
            <id>website</id>
            <url>scp://webhost.company.com/www/website</url>
        </site>
    </distributionManagement>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <junit.version>4.12</junit.version>
        <log4j.version>1.2.17</log4j.version>
        <lombok.version>1.16.18</lombok.version>
        <mysql.version>5.1.47</mysql.version>
        <druid.version>1.1.16</druid.version>
        <mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version>
    </properties>

    <build>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
            <plugins>
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>3.1.0</version>
                </plugin>
                <plugin>
                    <artifactId>maven-site-plugin</artifactId>
                    <version>3.7.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-project-info-reports-plugin</artifactId>
                    <version>3.0.0</version>
                </plugin>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <configuration>
                        <fork>true</fork>
                        <addResources>true</addResources>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-site-plugin</artifactId>
                <configuration>
                    <locales>en,fr</locales>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencyManagement>
        <dependencies>
            <!-- spring boot 2.2.2 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.2.2.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- spring cloud Hoxton.SR1 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.1.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>

            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>${druid.version}</version>
            </dependency>

            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.spring.boot.version}</version>
            </dependency>

            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
            </dependency>

            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${log4j.version}</version>
            </dependency>

            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
                <optional>true</optional>
            </dependency>

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <scope>runtime</scope>
                <optional>true</optional>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>

其中重点:

  1. <packaging>pom</packaging>父工程必须指定参数为pom
  2. <dependencyManagement>
    ...
    </dependencyManagement>可以被子项目继承的依赖信息,子项目引入相同依赖时可以不指定版本号,如果指定,则会使用自己的版本
从idea面板右侧的maven工具栏,先clean再install

3、创建子工程eureka-server-7001

右击父工程根目录,新建module,使用maven工具,选择jdk1.8,finish
pom文件添加依赖:

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <version>2.2.2.RELEASE</version>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    </dependencies>

pom文件其它不用改

创建src/main/resources/application.yml配置文件
内容如下(注意yml文件格式):

server:
  port: 7001

eureka:
  instance:
    hostname: localhost  #当前server名
  client:
    register-with-eureka: false   #此client不在eureka中注册,因为是其本身
    fetch-registry: false   #不要去注册中心获取其他服务的地址
    service-url:
      defaultZone: http://localhost2:7002/eureka/   #注册到eureka-server-7002

两个eureka相互注册实现高可用,也可使用多个

创建启动类com.learning.springcloud.Server7001Main

package com.learning.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

/**
 * @author xxxx
 * @version 1.0
 * @create 2020/8/2 4:44 下午
 */
@SpringBootApplication
@EnableEurekaServer
public class Server7001Main {
    public static void main(String[] args) {
        SpringApplication.run(Server7001Main.class,args);
    }
}

4、创建子工程eureka-server-7002

和eureka-server-7001步骤一致
pom文件直接复制7001的
只需对application.yml文件简单修改:

server:
  port: 7002

eureka:
  instance:
    hostname: localhost2  #当前server名
  client:
    register-with-eureka: false   #此client不在eureka中注册,因为是其本身
    fetch-registry: false   #不要去注册中心获取其他服务的地址
    service-url:
      defaultZone: http://localhost:7001/eureka/   #注册到eureka-server-7002

主启动类改个名就可以了

启动两个子工程,通过浏览器访问http:localhost:7001,看到如下页面及成功配置高可用server eureka.png

5、创建子工程commons-api

此工程是多个子工程用到的公用代码,将作为依赖引入其它子项目
pom文件引依赖:

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

创建类com.learning.springcloud.entities.Payment

package com.learning.springcloud.entities;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author xxxx
 * @version 1.0
 * @create 2020/8/2 5:21 下午
 */
@Data   //自动生成get、set方法
@AllArgsConstructor   //自动生成全参构造器
@NoArgsConstructor   //自动生成无参构造器
public class Payment {
    private Long id;
    private String serial;
}

创建类com.learning.springcloud.entities.CommonResult

package com.learning.springcloud.entities;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author xxxx
 * @version 1.0
 * @create 2020/8/2 5:21 下午
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonResult<T> {
    private Integer code;
    private String message;
    private T data;
}

clean项目、install项目

创建子工程payment-8001

pom文件加依赖

    <dependencies>
        <dependency>
            <groupId>org.learning.springcloud</groupId>
            <artifactId>commons-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <version>2.2.2.RELEASE</version>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </dependency>
    </dependencies>

创建src/main/resources/application.yml配置文件

server:
  port: 8001

spring:
  application:
    name: cloud-payment    #本微服务名称
  datasource:    #jdbs连接参数
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: org.gjt.mm.mysql.Driver
    url: jdbc:mysql://localhost:3306/db2020?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 12345687

eureka:
  client:
    register-with-eureka: true  #要注册到服务中心
    fetch-registry: true   #可以从服务中心获取其它服务信息
    service-url: http://localhost:7001/eureka,http://localhost2:7002/eureka   #向两个服务中心进行注册
  instance:
    instance-id: payment8001   #微服务的具体实例别名
    prefer-ip-address: true

mybatis:
  mapper-locations: classpath:mapper/*.xml    #mybatis配置mapper地址
  type-aliases-package: com.learning.springcloud.entities    #对应的实体类包

启动类com.learning.springcloud.Payment8001Main

package com.learning.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

/**
 * @author xxxx
 * @version 1.0
 * @create 2020/8/2 5:41 下午
 */
@SpringBootApplication
@EnableEurekaClient
public class Payment8001Main {
    public static void main(String[] args) {
        SpringApplication.run(Payment8001Main.class,args);
    }
}

创建接口com.learning.springcloud.dao.PaymentDao

package com.learning.springcloud.dao;

import com.learning.springcloud.entities.Payment;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

/**
 * @author xxxx
 * @version 1.0
 * @create 2020/8/2 5:42 下午
 */
@Mapper    //重要注解
public interface PaymentDao {
    Payment getPaymentById(@Param("id") Long id);
    int create(Payment payment);
}

创建src/main/resources/mapper/PaymentMapper.xml

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.learning.springcloud.dao.PaymentDao">
    <insert id="create" parameterType="Payment" useGeneratedKeys="true" keyProperty="id">
        insert into payment(serial) values (#{serial});
    </insert>

    <resultMap id="baseResultMap" type="com.learning.springcloud.entities.Payment">
        <id column="id" property="id" jdbcType="BIGINT"/>
        <id column="serial" property="serial" jdbcType="VARCHAR"/>
    </resultMap>

    <select id="getPaymentById" parameterType="Long" resultMap="baseResultMap">
        select * from payment where id=#{id};
    </select>
</mapper>

namespace属性别忘记

创建接口com.learning.springcloud.service.PaymentService及实现类com.learning.springcloud.service.impl.PaymentServiceImpl

package com.learning.springcloud.service;

import com.learning.springcloud.entities.Payment;

/**
 * @author xxxx
 * @version 1.0
 * @create 2020/8/2 6:14 下午
 */
public interface PaymentService {
    Payment getPaymentById(Long id);
    int create(Payment payment);
}
package com.learning.springcloud.service.impl;

import com.learning.springcloud.dao.PaymentDao;
import com.learning.springcloud.entities.Payment;
import com.learning.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * @author xxxx
 * @version 1.0
 * @create 2020/8/2 6:15 下午
 */
@Service
public class PaymentServiceImpl implements PaymentService {
    @Resource
    private PaymentDao paymentDao;

    @Override
    public Payment getPaymentById(Long id) {
        return paymentDao.getPaymentById(id);
    }

    @Override
    public int create(Payment payment) {
        return paymentDao.create(payment);
    }
}

com.learning.springcloud.controller.PaymentController

package com.learning.springcloud.controller;

import com.learning.springcloud.entities.CommonResult;
import com.learning.springcloud.entities.Payment;
import com.learning.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @author xxxx
 * @version 1.0
 * @create 2020/8/2 6:18 下午
 */
@RestController
@Slf4j
public class PaymentController {
    @Resource
    private PaymentService paymentService;

    @Value("${server.port}")
    private String serverPort;

    @GetMapping(value = "/payment/get/{id}")
    CommonResult<Payment> getPaymentById(@PathVariable("id") Long id){
        Payment result = paymentService.getPaymentById(id);
        log.info("******查询结果:{}", result);
        if (result != null){
            return new CommonResult<Payment>(200, "select success", result);
        }else {
            return new CommonResult<Payment>(444, "select fail");
        }
    }

    @PostMapping(value = "/payment/create")
    CommonResult<Integer> create(@RequestBody Payment payment){
        log.info("~~~~~~~~~~~~~XXXXX:{}",payment);
        int result = paymentService.create(payment);
        log.info("******插入结果:" + result);
        if (result > 0){
            return new CommonResult<>(200, "create success, server_port:" + serverPort, result);
        }else {
            return new CommonResult<>(444, "create fail");
        }
    }
}

子项目payment-8002

基本复制8001
application.yml配置文件有所变化
端口改为8002
instance-id为payment8002
可以启动服务器后再启动两个payment微服务,在浏览器上进行访问验证是否成功http://localhost:8002/payment/get/1

创建子工程order-80

pom文件依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <version>2.2.2.RELEASE</version>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.learning.springcloud</groupId>
            <artifactId>commons-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

application.yml

server:
  port: 80

spring:
  application:
    name: order-server-80

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:7001/eureka,http://localhost2:7002/eureka

ribbon:
  ReadTimeout: 5000
  ConnectTimeout: 5000

logging:
  level:
    com.springcloud.demo.services.PaymentFeignService: debug

com.learning.springcloud.config.FeignConfig

package com.learning.springcloud.config;

import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author xxxx
 * @version 1.0
 * @create 2020/8/3 10:22 上午
 */
@Configuration
public class FeignConfig {
    @Bean
    public Logger.Level feignLoggerLevel(){
        return Logger.Level.FULL;
    }
}

com.learning.springcloud.service.OrderPaymentService

openfeign通过ribbon实现负载均衡

import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;

/**
 * @author xxxx
 * @version 1.0
 * @create 2020/8/3 10:09 上午
 */
@Service
@FeignClient(value = "cloud-payment")
public interface OrderPaymentService {
    @GetMapping(value = "/payment/get/{id}")
    CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);

    @GetMapping(value = "/payment/create")
    CommonResult<Integer> create(@RequestBody Payment payment);
}

com.learning.springcloud.controller.OrderPaymentController

package com.learning.springcloud.controller;

import com.learning.springcloud.entities.CommonResult;
import com.learning.springcloud.entities.Payment;
import com.learning.springcloud.service.OrderPaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @author xxxx
 * @version 1.0
 * @create 2020/8/3 9:55 上午
 */
@RestController
@Slf4j
public class OrderPaymentController {

    @Resource
    private OrderPaymentService orderPaymentService;

    @GetMapping(value = "/order/payment/get/{id}")
    CommonResult<Payment> getPaymentById(@PathVariable("id") Long id){
        return orderPaymentService.getPaymentById(id);
    }

    @GetMapping(value = "/order/payment/create")
    CommonResult<Integer> create(Payment payment){
        return orderPaymentService.create(payment);
    }

}

一个简单的cloud后端服务已完成,实现类注册中心的高可用和子服务的负载均衡,启动顺序为先启动两个eureka注册中心,再启动其它微服务,然后可以通过浏览器访问验证http://localhost/order/payment/create?id=3&serial=ere

本文章参照尚硅谷周阳老师视频完成,进一步学习可以网上搜索他的视频

相关文章

网友评论

      本文标题:spring cloud 入门学习【结合实例】——开发工具为id

      本文链接:https://www.haomeiwen.com/subject/gibprktx.html