SpringCloud学习笔记01

这篇博客详细介绍了SpringCloud的学习过程,包括微服务架构理论、Eureka服务治理,从父工程创建到子模块构建,再到服务注册与发现。内容涵盖Eureka集群的搭建与服务注册,同时提及了Zookeeper作为注册中心的使用。适合初学者系统学习SpringCloud。
摘要由CSDN通过智能技术生成

目录

一、前言闲聊和课程说明

二、零基础微服务架构理论入门

三、第二季Boot与Cloud版本选型

四、Cloud组件停更说明

五、父工程Project空间新建

六、父工程pom文件

七、复习DependencyManagement和Dependencies

八、支付模块构建(上)

九、支付模块构建(中)

十、支付模块构建(下)

十一、热部署 Devtools

十二、消费者订单模块(上)

十三、消费者订单模块(下)

十四、工程重构

十五、Eureka基础知识

十六、EurekaServer服务端安装

十七、支付微服务8001入驻进eurekaServer

十八、订单微服务80入驻eurekaServer

十九、Eureka集群原理说明

二十、Eureka集群环境构建

二十一、订单支付两个微服务注册进Eureka集群

二十二、支付微服务集群配置

二十三、actuator微服务信息完善

二十四、服务发现 Discovery

二十五、Eureka自我保护理论知识

二十六、怎么禁止自我保护

二十七、Eureka停更说明

二十八、支付服务注册进zookeeper

二十九、临时还是持久节点

三十、订单服务注册进zookeeper


一、前言闲聊和课程说明

1、课程内容(SpringCloud + SpringCloud alibaba)

2、技术要求

     java8+maven+git、github+Nginx+RabbitMQ+SpringBoot2.0

3、听课对象,开局爬楼

         学生  零基础+非科班+文科妹子... JVM/JUC/GC/Nginx...

         阶段  零(1-4章)-初(5-9章)-中(10-16章)-高(17-21章)

4、持续学习 (不在能知,乃在能行

语言少了,思想就出来了

二、零基础微服务架构理论入门

理论面试上很重要

01、微服务架构概念

微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相调用、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相协作(通常是基于HTTP协议的RESTful API)。每个服务都围绕着具体业务进行构建,并且能够被独立的部署到生产环境、类生产环境等。另外,应当尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建

==============================

比如说:我现在下了一个订单,要去调用库存,库存调了,要去付钱调支付,支付调了,要去调仓储和物流,物流调了,送货成功了,要给人家增加积分等等

一个一个的模块就是我们用SpringBoot开发的一个一个的微服务,以前只有一套only one,多个服务需要有种机制,将其管理起来

Springboot就是一个一个的提供功能的微服务(订单模块、库存模块、仓储模块、积分模块、支付模块),服务之间需要互相的协调、配合,最终运行在独立的进程中

两种方式:

1、手机华为的,笔记本电脑Thinkpad联想的,智能家电天猫精灵的,平板电脑苹果的,生活箱包其他品牌的,有点类似于组装机

2、我们只有一个服务品牌商,手机、电脑等等都是苹果品牌的,有点类似于,假设你这一个主题需要多种落地的维度和技术支撑,要么就是品牌的,要么就是杂交的

     我们现在不想东奔西走,就有一家厂家提供一揽子解决方案,把我们这种维度统一地封装在一块,比如小米公司

     一个厂家提供的话,兼容性非常好

基于分布式的微服务架构

SpringCloud的官网,中间是microservices,那个图标就是SpringBoot,一个一个SpringBoot开发出来的东东就是一个个具体的落地功能

融合协调组装一切:使构建分布式系统变得更加容易

API Gateway:网关

breaker dashboard:监控仪表盘

service registry:服务注册

message brokers:消息中间件

databases:数据库

distributed tracing:分布式的链路追踪

config dashboard:配置中心

谈谈你对分布式微服务架构的理解?

你说你是数字化生活,不能说只有手机,只有电脑吧,肯定有一堆东西

你说你是分布式的微服务架构,你也不可能只使用一种技术,一定是分布式微服务架构的一整套体系与体系之间的较量和对抗,所以说这么多落地的技术和维度构成了分布式微服务架构的体系,它强的不是一个个体,强是在一个整体,技术经理考虑的就是通盘、整体,程序员想的就是落地的一个具体的功能

SpringCloud是分布式微服务架构技术的一种体现,它应该有多种维度

SpringCloud=分布式微服务架构的一站式解决方案,是多种微服务架构落地技术的集合体,俗称微服务全家桶

SpringCloud俨然已成为微服务开发的主流技术栈

大厂微服务架构

1、京东

2、阿里

3、京东金融

无业务基础服务与业务型基础服务

03、SpringCloud技术栈

目前微服务架构(通用的)

过来以后,框框里面的就是SpringBoot和SpringCloud的体系里面的,外面的就是第三方的

首先过来,要通过一个微服务网关(NETFLIX),SpringCloud其实是抄了NETFLIX公司

大面上都是通过一个服务网关,找了注册,然后去配置中心读取,n多个SpringBoot开发的微服务来进行协调和调度,需要认证、有容错和限流、降级、熔断等等

最终整个的服务运作了,我们需要有监控、有日志、有健康检查和告警

天上飞的理念,必然有落地的实现

SpringCloud通过网关,调用这些负载均衡,每一个微服务A、B、C来进行调度

目录

三、第二季Boot与Cloud版本选型

SpringBoot是一种技术,SpringCloud是分布式微服务架构一揽子解决方案有多种技术的落地

SpringBoot2.X版和SpringCloud H版

SpringCloud官网查看

更详细的版本对应查看方法:https://start.spring.io/actuator/info

json在线工具:在线工具 - 你的工具箱

最终版本要求

四、Cloud组件停更说明

官方文档

Spring Cloud

关于Cloud各种组件的停更/升级/替换

由停更引发的“升级惨案”:

停更不停用:1、被动修复bugs  2、不再接受合并请求 3、不再发布新版本

SpringCloud是全家桶,是分布式微服务技术的集大成者,我们现在主要学习企业里使用的主流技术

理念会有落地的实现

dubbo做服务调用,zookeeper做服务的注册中心

1、

2、

微服务都需要有一个网关作为一个总的接入口进行服务的协调、调度

五、父工程Project空间新建

订单-支付模块微服务

约定 > 配置 > 编码

步骤1:

步骤2:

步骤3:注解生效激活

步骤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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.nanjing.springcloud</groupId>
    <artifactId>cloud2021</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging><!--总的父工程->

    <!--统一管理jar包版本-->
    <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>

    <!--子模块继承之后,提供作用:锁定版本+子modlue不用写groupId和version -->
    <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>
            <!--spring cloud alibaba 2.1.0.RELEASE-->
            <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>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                    <addResources>true</addResources>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

七、复习DependencyManagement和Dependencies

1、

2、

3、

父工程创建完成执行mvn:install将父工程发布到仓库方便子工程继承

八、支付模块构建(上)

订单模块(order)可以来调用支付模块(payment)

微服务模块

1、建module(cloud-provider-payment8001

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>cloud2021</artifactId>
        <groupId>com.nanjing.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-provider-payment8001</artifactId>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency><!--引入自己定义的api通用包,可以使用 Payment支付Entity-->
            <groupId>com.nanjing.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>

        <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>

        <!--https://mvnrepository.com/artifact/com.alibaba/druid-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
        <!--https://mvnrepository.com/artifact/mysql/mysql-connector-java-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-jdbc-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <!--https://mvnrepository.com/artifact/org.projectlombok/lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

3、写YML

server:
  port: 8001

spring:
  application:
    name: cloud-payment-service #服务名称
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource  # 当前数据源操作类型
    driver-class-name: org.gjt.mm.mysql.Driver    # mysql驱动包
    url: jdbc:mysql://localhost:3306/springcloud?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456

mybatis:
  mapperLocations: classpath:mapper/*.xml
  type-aliases-package: com.nanjing.springcloud.entities

4、主启动

@SpringBootApplication
public class PaymentMain8001 {
    public static void main(String[] args) {

        SpringApplication.run(PaymentMain8001.class,args);
    }
}

5、业务类

九、支付模块构建(中)

vue-controller-service-dao-mysql   返回 json

步骤1:

DROP TABLE IF EXISTS `payment`;
CREATE TABLE `payment` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `serial` varchar(200) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4;

步骤2:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Payment implements Serializable {

    private Long id;
    private String serial;

}

步骤3:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonResult<T> {

    private Integer code;
    private String message;
    private T data;

    public CommonResult(Integer code, String message) {
        this(code, message, null);
    }

}

步骤4:

@Mapper
public interface PaymentDao {

    public int create(Payment payment);

    public Payment getPaymentById(@Param("id") Long id);
}

步骤5:

<?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.nanjing.springcloud.dao.PaymentDao">

    <insert id="create" parameterType="Payment" useGeneratedKeys="true" keyProperty="id">
        insert into payment(serial)
        values (#{serial});
    </insert>

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

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


</mapper>

步骤6:

public interface PaymentService {

    public int create(Payment payment);

    public Payment getPaymentById(@Param("id") Long id);
}

步骤7:

@Service
public class PaymentServiceImpl implements PaymentService {

    @Resource
    private PaymentDao paymentDao;

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

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

步骤8:

@RestController
@Slf4j
public class PaymentController {

    @Resource
    private PaymentService paymentService;

    @PostMapping(value = "/payment/create")
    public CommonResult create(@RequestBody Payment payment){
        int result = paymentService.create(payment);
        log.info("插入结果: "+result);
        if(result > 0) {
            return new CommonResult(200,"插入数据库成功",result);
        }else {
            return new CommonResult(444,"插入数据库失败",null);
        }
    }

    @GetMapping(value = "/payment/get/{id}")
    public CommonResult getPaymentById(@PathVariable("id") Long id){
        Payment payment = paymentService.getPaymentById(id);
        log.info("查询结果: "+payment);
        if(payment != null) {
            return new CommonResult(200,"查询成功",payment);
        }else {
            return new CommonResult(444,"没有对应记录,查询ID: "+id,null);
        }
    }

}

十、支付模块构建(下)

十一、热部署 Devtools

步骤1(子工程):

<!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

步骤2(父工程):

<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                    <addResources>true</addResources>
                </configuration>
            </plugin>
        </plugins>
    </build>

步骤3:

步骤4:

十二、消费者订单模块(上)

步骤1:

<?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>cloud2021</artifactId>
        <groupId>com.nanjing.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-consumer-order80</artifactId>

    <dependencies>

        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>com.nanjing.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>

        <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <!--https://mvnrepository.com/artifact/org.projectlombok/lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

步骤2:

@Configuration
public class ApplicationContextConfig {

    @Bean
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

步骤3:

package com.nanjing.springcloud.controller;

import com.nanjing.springcloud.entities.CommonResult;
import com.nanjing.springcloud.entities.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
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 javax.annotation.Resource;

@RestController
@Slf4j
public class OrderController {

    public static final String PAYMENY_URL = "http://localhost:8001";

    @Resource
    private RestTemplate restTemplate;

    @GetMapping("/comsumer/payment/create")
    public CommonResult<Payment> create(Payment payment){
        return restTemplate.postForObject(PAYMENY_URL+"/payment/create",payment,CommonResult.class);
    }

    @GetMapping("/comsumer/payment/get/{id}")
    public CommonResult<Payment> getPayment(@PathVariable("id") Long id){
        return restTemplate.getForObject(PAYMENY_URL+"/payment/get/"+id,CommonResult.class);
    }

}

RestTemplate提供了多种便捷访问远程http服务的方法

是一种简单便捷的访问restful服务模块类,是Spring提供的用于访问Rest服务的客户端模板工具集

RestTemplate就是完成80到8001端口的远程调用,一种调用接口方式的封装,与httpClient异曲同工

需要把 RestTemplate 注入到SpringBoot的容器中

十三、消费者订单模块(下)

1、注意post请求时 不要忘记@RequestBody注解

2、开启 Run DashBoard

 <component name="RunDashboard">
    <option name="configurationTypes">
      <set>
        <option value="SpringBootApplicationConfigurationType" />
      </set>
    </option>
  </component>

十四、工程重构

抽取entities实体类到公共的api模块

步骤1:

<?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>cloud2021</artifactId>
        <groupId>com.nanjing.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-api-commons</artifactId>

    <dependencies>
        <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!--https://mvnrepository.com/artifact/cn.hutool/hutool-all-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.1.0</version>
        </dependency>
    </dependencies>

</project>

十五、Eureka基础知识(第五章)

已经停止更新了

理论很重要

1、

2、服务治理

3、服务注册与发现

Eureka两个组件

十六、EurekaServer服务端安装

步骤1:

<?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>cloud2021</artifactId>
        <groupId>com.nanjing.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-eureka-server7001</artifactId>

    <dependencies>
        <!--https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

        <dependency>
            <groupId>com.nanjing.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <!--https://mvnrepository.com/artifact/org.projectlombok/lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
    </dependencies>

</project>


步骤2:

server:
  port: 7001

eureka:
  instance:
    hostname: localhost #eureka服务端的实例名字
  client:
    #表示不向注册中心注册自己
    register-with-eureka: false
    #表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务
    fetch-registry: false
    service-url:
    #设置与eureka server交互的地址查询服务和注册服务都需要依赖这个地址 ---单机版     
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
     

步骤3:启动类

@SpringBootApplication
@EnableEurekaServer  //表明这是Eureka的服务注册中心
public class EurekaMain7001 {
    public static void main(String[] args) {

        SpringApplication.run(EurekaMain7001.class,args);
    }
}

因为没有注册服务进来当然不可能有服务被发现

十七、支付微服务8001入驻进eurekaServer

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

步骤1:

server:
  port: 8001

spring:
  application:
    name: cloud-payment-service #服务名称
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource  # 当前数据源操作类型
    driver-class-name: org.gjt.mm.mysql.Driver    # mysql驱动包
    url: jdbc:mysql://localhost:3306/springcloud?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456

eureka:
  client:
    #表示是否将自己注册进EurekaServer默认为true
    register-with-eureka: true
    #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓。集群必须设置为true才能配合ribbon使用负载均衡
    fetchRegistry: true
    service-url:
      defaultZone: http://localhost:7001/eureka  单机版

mybatis:
  mapperLocations: classpath:mapper/*.xml
  type-aliases-package: com.nanjing.springcloud.entities

步骤2:加上 @EnableEurekaClient 注解

@SpringBootApplication
@EnableEurekaClient
public class PaymentMain8001 {
    public static void main(String[] args) {

        SpringApplication.run(PaymentMain8001.class,args);
    }
}

十八、订单微服务80入驻eurekaServer

步骤1:

server:
  port: 8080

spring:
    application:
        name: cloud-order-service

eureka:
  client:
    #表示是否将自己注册进EurekaServer默认为true
    register-with-eureka: true
    #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓。集群必须设置为true才能配合ribbon使用负载均衡
    fetchRegistry: true
    service-url:
      defaultZone: http://localhost:7001/eureka  单机版
     

十九、Eureka集群原理说明

高可用,堆叠一定就是集群效应,单机版结束了。

解决方法:搭建Eureka注册中心集群,实现负载均衡+故障容错

对外暴露是一个整体,里面有多台Eureka,互相注册,相互守望,7001指向7002,相反一样。总之一句话,我一定要有我这个圈子里面所有兄弟的全部相关信息

二十、Eureka集群环境构建

集群指向其它eureka

server:
  port: 7001

eureka:
  instance:
    hostname: eureka7001.com #eureka服务端的实例名字
  client:
    #表示不向注册中心注册自己
    register-with-eureka: false
    #表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务
    fetch-registry: false
    service-url:
    #设置与eureka server交互的地址查询服务和注册服务都需要依赖这个地址
      # 单机版     defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
      # 集群指向其它eureka
      defaultZone: http://eureka7002.com:7002/eureka/
     

二十一、订单支付两个微服务注册进Eureka集群

步骤1:集群版需要指向多个Eureka地址:defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/  

server:
  port: 8001

spring:
  application:
    name: cloud-payment-service #服务名称
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource  # 当前数据源操作类型
    driver-class-name: org.gjt.mm.mysql.Driver    # mysql驱动包
    url: jdbc:mysql://localhost:3306/springcloud?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456

eureka:
  client:
    #表示是否将自己注册进EurekaServer默认为true
    register-with-eureka: true
    #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓。集群必须设置为true才能配合ribbon使用负载均衡
    fetchRegistry: true
    service-url:
#      defaultZone: http://localhost:7001/eureka  单机版
#       defaultZone: http://eureka7001.com:7001/eureka/
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/  

mybatis:
  mapperLocations: classpath:mapper/*.xml
  type-aliases-package: com.nanjing.springcloud.entities

二十二、支付微服务集群配置

服务提供者也是集群

负载均衡

步骤1:加入端口号显示

@RestController
@Slf4j
public class PaymentController {

    @Resource
    private PaymentService paymentService;

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

    @PostMapping(value = "/payment/create")
    public CommonResult create(@RequestBody Payment payment){
        int result = paymentService.create(payment);
        log.info("插入结果: "+result);
        if(result > 0) {
            return new CommonResult(200,"插入数据库成功,serverPort: "+serverPort,result);
        }else {
            return new CommonResult(444,"插入数据库失败",null);
        }
    }

    @GetMapping(value = "/payment/get/{id}")
    public CommonResult getPaymentById(@PathVariable("id") Long id){
        Payment payment = paymentService.getPaymentById(id);
        log.info("查询结果: "+payment);
        if(payment != null) {
            return new CommonResult(200,"查询成功,serverPort: "+serverPort,payment);
        }else {
            return new CommonResult(444,"没有对应记录,查询ID: "+id,null);
        }
    }
}

步骤2:访问ip不能够写死  public static final String PAYMENY_URL = "http://CLOUD-PAYMENT-SERVICE"

@RestController
@Slf4j
public class OrderController {

//    public static final String PAYMENY_URL = "http://localhost:8001";
    public static final String PAYMENY_URL = "http://CLOUD-PAYMENT-SERVICE";

    @Resource
    private RestTemplate restTemplate;

    @GetMapping("/comsumer/payment/create")
    public CommonResult<Payment> create(Payment payment){
        return restTemplate.postForObject(PAYMENY_URL+"/payment/create",payment,CommonResult.class);
    }

    @GetMapping("/comsumer/payment/get/{id}")
    public CommonResult<Payment> getPayment(@PathVariable("id") Long id){
        return restTemplate.getForObject(PAYMENY_URL+"/payment/get/"+id,CommonResult.class);
    }

    @GetMapping("/comsumer/payment/getForEntity/{id}")
    public CommonResult<Payment> getPayment2(@PathVariable("id") Long id){
        ResponseEntity<CommonResult> entity = restTemplate.getForEntity(PAYMENY_URL+"/payment/get/"+id,CommonResult.class);

        if(entity.getStatusCode().is2xxSuccessful()){
            return entity.getBody();
        }else {
            return new CommonResult<>(444,"操作失败");
        }
    }
}

步骤3:使用@LoadBalanced注解赋予RestTemplate负载均衡的能力

@Configuration
public class ApplicationContextConfig {

    @Bean
    @LoadBalanced //使用@LoadBalanced注解赋予RestTemplate负载均衡的能力
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

二十三、actuator微服务信息完善

健康检查

配置文件

健康检查 /actuator/health

  instance:
    instance-id: payment8001  #修改主机名称
    prefer-ip-address: true   #访问路径可以显示IP地址

二十四、服务发现 Discovery

对于注册进eureka里面的微服务,可以通过服务发现来获得该服务的信息(主机名称、端口号)

步骤1:

@RestController
@Slf4j
public class PaymentController {

    @Resource
    private DiscoveryClient discoveryClient;

    @GetMapping(value = "/payment/discovery")
    public Object discovery(){
        List<String> services = discoveryClient.getServices();
        for (String element : services) {
            log.info("******element"+element);
        }

        List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
        for (ServiceInstance instance : instances) {
            log.info(instance.getServiceId()+"\t"+instance.getHost()+"\t"+instance.getPort()+"\t"+instance.getUri());
        }

        return this.discoveryClient;
    }
}

步骤2:加上@EnableDiscoveryClient注解

@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
public class PaymentMain8001 {
    public static void main(String[] args) {

        SpringApplication.run(PaymentMain8001.class,args);
    }
}

输出:

二十五、Eureka自我保护理论知识

概述:

保护模式主要用于一组客户端和Eureka Server之间存在网络分区场景下的保护。一旦进入保护模式,Eureka Server将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据,也就是不会注销任何微服务。

如果在Eureka Server的首页看到以下这段提示,则说明Eureka进入了保护模式:

 1、高可用

2、

3、

4、

二十六、怎么禁止自我保护

步骤1:以单机版测试

    # 关闭自我保护机制,保证不可用服务被及时踢除
    enable-self-preservation: false
    eviction-interval-timer-in-ms: 2000

步骤2:

    # Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒)
    lease-renewal-interval-in-seconds: 1
    # Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将踢除服务
    lease-expiration-duration-in-seconds: 2

二十七、Eureka停更说明

英文版本

Home · Netflix/eureka Wiki · GitHub

二十八、支付服务注册进zookeeper

步骤一:导入zookeeper相关依赖

<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-zookeeper-discovery -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
            <!--排除zk3.5.3-->
            <exclusions>
                <exclusion>
                    <groupId>org.apache.zookeeper</groupId>
                    <artifactId>zookeeper</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--添加zk 3.4,9版本-->
        <!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.9</version>
        </dependency>

步骤二:

#8004 表示注册到zookeeper服务器的支付服务提供者端口号
server:
  port: 8004

# 服务别名---注册zookeeper到注册中心名称
spring:
  application:
    name: cloud-provider-payment
  cloud:
    zookeeper:
      connect-string: 192.168.142.128:2181

步骤三:

@SpringBootApplication
@EnableDiscoveryClient  //该注解用于向使用consul或者zookeeper作为注册中心时注册服务
public class PaymentMain8004 {
    public static void main(String[] args) {

        SpringApplication.run(PaymentMain8004.class,args);
    }
}

步骤四:

@RestController
@Slf4j
public class PaymentController {

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

    @GetMapping(value = "/payment/zk")
    public String paymentzk() {
        return "springcloud with zookeeper:" + serverPort + "\t" + UUID.randomUUID().toString();
    }

}

步骤五:

步骤六:使用json工具查看注册到zookeeper里的信息

二十九、临时还是持久节点

服务节点是临时节点还是持久节点? 临时节点

三十、订单服务注册进zookeeper

步骤1:

server:
  port: 8080

spring:
  application:
    name: cloud-consumer-order
  cloud:
    #注册到 zookeeper地址
    zookeeper:
      connect-string: 192.168.142.128:2181

步骤2:

@SpringBootApplication
@EnableDiscoveryClient //该注解用于向使用consul或者zookeeper作为注册中心时注册服务
public class OrderZKMain80 {
    public static void main(String[] args) {

        SpringApplication.run(OrderZKMain80.class,args);
    }
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值