springCloud学习【一】:服务的注册发现与消费【实例】

springCloud之微服务的注册发现与消费


个人学习记录而已,没事就回来看看,给自己涨记性

不做名词解释,各种名词解释百度一堆堆
文章总结写在末尾点个赞鼓励一下?
文章有点长,目录是个好东西啊
哪里不对留言讨论,拜托描述清楚
废话连篇:凡心所向,素履所往;

代码地址

☆本文章的代码地址——需单独下载
★★项目完整代码——gitee地址:不断更新

准备:新建一个空的maven项目用来当父项目【CloudDemo】我就是拿他当个根目录而已

新建空的maven父项目
在这里插入图片描述

一、项目准备:CloudDemo仅当作父项目使用【各个项目的根目录而已】

1、删除没用的东西
2、maven配置
3、编译jdk设置
4、项目编码设置
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、创建注册中心模块cloud-registry SpringBoot项目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注册中心选择的eureka Server 其他的依赖 个人习惯dev和lombok 然后一路下一步完成

完整项目结构:

在这里插入图片描述
cloud-registry-pom.xml内容【默认最新的springCloud版本,Hoxton.SR8】

<?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>2.3.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.crazy</groupId>
    <artifactId>cloud-registry</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>cloud-registry</name>
    <description>注册中心模块</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR8</spring-cloud.version>
    </properties>

    <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-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </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>
            </exclusions>
        </dependency>
    </dependencies>

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

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

</project>

项目依赖
在这里插入图片描述

三、注册中心的配置【yml格式】

在这里插入图片描述

server:
  port: 8770  #端口
  application:
    name: Eureka-Registry #当前模块项目的服务名称

eureka:
  client:
    register-with-eureka: false #是否将自己注册到Eureka Server
    fetch-registry: false #是否从Eureka Server获取注册信息
    service-url:
      defaultZone: http://localhost:${server.port}/eureka/   #当前注册中心的地址,其他的服务需要注册到这里

启动类增加Eureka的配置注解 @EnableEurekaServer 注解解释 :激活eureka的服务器配置
在这里插入图片描述

四、搞定,注册中心就这么就没球了,启动点个赞鼓励一下?

在这里插入图片描述
访问路径localhost:8770即可打开Eureka的管理界面【直接IP:端口就可以,不用加/eureka】
后面注册进来的服务会在Instances currently registered with Eureka展示
在这里插入图片描述

五、去搞一个服务cloud-service【服务提供者】注册到eureka中,SpringBoot项目

还是新建一个moudle,依赖选择Eureka Discovery Client
在这里插入图片描述
在这里插入图片描述
pom.xml内容添加了web依赖

<?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>2.3.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.crazy</groupId>
    <artifactId>cloud-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>cloud-service</name>
    <description>服务提供者,只提供接口服务</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR8</spring-cloud.version>
    </properties>

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

        <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>
        <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>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.3.4.RELEASE</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

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

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

</project>

六、服务提供者service的配置

在这里插入图片描述

server:
  port: 8771 #设置服务提供者的端口号

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8770/eureka/  #注册到那里的注册中心
      
spring:
  application:
    name: Eureka-Service  #这个项目模块所提供服务的名称

在启动类上添加注解 @EnableEurekaClient
这里有点迷,最后的总结里面有说明

在这里插入图片描述

七、依次启动

在这里插入图片描述
先启动registry 然后再启动 service

再次打开Eureka的管理界面localhost:8770

可以发现服务提供者已经注册到注册中心了

在这里插入图片描述
点个赞鼓励一下?

八、服务注册了, 提供两个接口服务用来消费(调用)

给他提供两个最简单的服务接口

1、接口一返回一个字符串
2、接口二返回一个实体

启动类同级创建包,然后就是web开发的路子controller和service和mapper和pojo(moudle,entity)实体层和工具啊配置啊啥的各种包路径

在这里插入图片描述

package com.crazy.controller;

import com.crazy.pojo.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Description 提供两个简单的服务
 * @Author Crazy
 * @Date 2020/10/10 14:52
 * @Copyright
 */
@RestController
@RequestMapping("/test")
public class TestController {
    /**
     * 接口服务一
     */
    @RequestMapping("/string")
    public String hello(String str) {
        System.out.println(">>>>>>进入/test/string>>>>>>传入的值:" + str );
        //service层和impl以及mapper层略过

        return "你好:" + str;
    }

    /**
     * 接口服务二
     */
    @RequestMapping("/getUser")
    public User getUser() {
        System.out.println(">>>>>>进入/test/getUser");
        //service层和impl以及mapper层略过
        User u = new User();
        u.setId(1);
        u.setUserName("疯疯颠颠");
        u.setPassword("Crazy123");
        return u;
    }

}

在这里插入图片描述
重新启动cloud-service 测试
在这里插入图片描述
测试:编码也好,浏览器也好,我用的postman
在这里插入图片描述
在这里插入图片描述

九、搞定,在弄个服务消费者cloud-consume SpringBoot项目

消费方式两种,这个模块是基于Ribbon+RestTemplate方式去消费调用服务
新建一个模块moudle【服务消费者cloud-consume】
依赖如下
在这里插入图片描述
项目配置文件
在这里插入图片描述

server:
  port: 8772 #设置服务提供者的端口号

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8770/eureka/  #注册到那里的注册中心

spring:
  application:
    name: Eureka-Consume  #这个项目模块所提供服务的名称
服务消费调用的方式有很多点个赞鼓励一下?
1、第一种直接调用 不经过注册中心需要一个RestTemplate的客户端

在这里插入图片描述
源码解释为客户端负载均衡器
在这里插入图片描述

package com.crazy.beans;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * @Description TODO
 * @Author Crazy
 * @Date 2020/10/10 15:35
 * @Copyright
 */
@Configuration
public class Beans {

    @Bean
    @LoadBalanced //标记一个RestTemplate为客户端负载均衡
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

controller直接调用的,没有走本模块的service以及mapper层

在这里插入图片描述

package com.crazy.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * @Description 消费者调用服务Demo
 * @Author Crazy
 * @Date 2020/10/10 15:14
 * @Copyright
 */
@RestController
@RequestMapping("/consume")
public class ConsumeController {

    /**
     * 第一种消费调用服务的方式
     */
    @RequestMapping("/one")
    public String helloWorld(String s) {
        System.out.println("进入/consume/one>>>>>>传入的值为:" + s);

        String One = new RestTemplate().getForObject("http://localhost:8771/test/string?str=" + s, String.class);
        System.out.println("第一种>>>>>>:"+One);


        return ">>>>>>调用返回的是:"+One;
    }

}

启动cloud-consume项目 消费者也到注册中心了

在这里插入图片描述

测试

在这里插入图片描述
消费者控制台打印的信息

在这里插入图片描述
服务提供者控制台打印的信息

在这里插入图片描述
调用实体返回值 这里只在控制台打印,没有返回实体

在这里插入图片描述
打印信息

在这里插入图片描述

2、第二种消费方式【根据服务名 获取服务列表 访问某个服务的网络位置】

在这里插入图片描述

    @Autowired
    private LoadBalancerClient loadBalancerClient;
    
	 /**
     * 第二种消费调用服务方式:根据服务名 获取服务列表 并访问某个服务的网络位置。
     */
    @RequestMapping("/two")
    public String helloTwo(String s){
        System.out.println("进入/consume/two>>>>>>传入的值为:" + s);

        RestTemplate restTemplate = new RestTemplate();
        //获取服务信息
        ServiceInstance serviceInstance = loadBalancerClient.choose("EUREKA-SERVICE");
        String Two = restTemplate.getForObject("http://"+serviceInstance.getHost()+":"+serviceInstance.getPort()+"/test/string?str="+s,String.class);

        //getForObject也可以返回实体数据  区别:直接返回请求的body里面的实体
        User user = new RestTemplate().getForObject("http://"+serviceInstance.getHost()+":"+serviceInstance.getPort()+"/test/getUser?str=" + s, User.class);
        System.out.println(">>>>>>调用返回的实体数据:" + user.toString());


        return ">>>>>>调用返回的是:" + Two;
    }

测试
在这里插入图片描述
控制台信息
在这里插入图片描述
在这里插入图片描述

3、第三种Ribbon+restTemplate注入的方式

控制层
在这里插入图片描述
service层
在这里插入图片描述
service实现层执行调用消费服务
在这里插入图片描述
service实现层代码

package com.crazy.service.impl;

import com.crazy.pojo.User;
import com.crazy.service.ConsumeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

/**
 * @Description TODO
 * @Author Crazy
 * @Date 2020/10/10
 * @Copyright
 */
@Service
public class ConsumeServiceImpl implements ConsumeService {

    @Autowired
    private RestTemplate rest;

    @Override
    public String testResult(String s) {
        //restTemplate的对GET请求进行调用的两种请求方式 一
        String str = rest.getForObject("http://EUREKA-SERVICE/test/string?str={1}", String.class,s);

        //restTemplate的对GET请求进行调用的两种请求方式 二  上面的方式也可以响应为实体
        ResponseEntity<User> forEntity = rest.getForEntity("http://EUREKA-SERVICE/test/getUser", User.class);
        System.out.println(">>>>>>测试getForEntity返回值:"+forEntity.getBody());

        //其他还有POST的各种API以后慢慢测试

        return str;
    }
}

测试
在这里插入图片描述
控制台打印信息

在这里插入图片描述
在这里插入图片描述
beans也可以直接写道启动类中加载
在这里插入图片描述

十、再弄个服务消费者cloud-consume-feign SpringBoot项目

第二种消费服务的方式,基于Feign去消费服务 两种消费方式区别比较写在最后
新建一个模块moudle【服务消费者cloud-consume-feign】
依赖如下
在这里插入图片描述

此模块项目配置文件

server:
  port: 8773 #设置服务提供者的端口号

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8770/eureka/  #注册到那里的注册中心

spring:
  application:
    name: Eureka-Consume-Feign  #这个项目模块所提供服务的名称

基于feign消费的方式,是以 HTTP 接口的形式暴露的,使用起来就像调用自己本地方式似的。
使用:
1、需要定义一抽象的个接口,不需要实现,直接定义了接口就行,简单增加一些注解

在这里插入图片描述
2、controller里面注入定义的Service,直接调用即可。

在这里插入图片描述
3、启动类增加一个注解,标记一下打开feign的客户端
在这里插入图片描述
启动-测试
在这里插入图片描述
区别?就记一下较为明显的区别吧

ribbon需要自己去构建服务的IP:端口:映射等
feign 只需要抽象方法里定义好服务名和映射路径,不需要知道服务的提供者是哪个服务端

十一、复制几个服务实现调用

注册中心现有的服务有

两个,一个服务提供者,一个服务消费者。多搞几个服务提供者玩玩?
服务层增加点东西,打印一下,每个服务的端口信息
两个都挺好用,都支持负债均衡
在这里插入图片描述
在这里插入图片描述
然后把服务多复制两个出来通过VM命令改一下端口
在这里插入图片描述
选中service直接复制
在这里插入图片描述
点击复制出来的服务Environment 分别去修改这两个复制出来的服务的端口号 -Dserver.port=8773这里一个8773一个8774
现有的端口号
8770 注册中心
8771 服务提供者
8772 服务消费者
8773-8774是复制出来的两个服务提供者

完了之后点击-应用-OK
在这里插入图片描述
服务全部重启:顺序 registry-service-service01-service-02-consume 也就是一个注册中心,三个服务提供者,一个服务消费者
eureka管理界面中显示service服务有三个了,端口分别是8774-8771-8773 但是名字一样
在这里插入图片描述
再来测试消费的方式123,就3吧

在这里插入图片描述
控制台信息
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
three的请求,方法内部调用了两次服务,一次进了8774,一次进了8773,8773没有打印,所以页面只显示8774,多来几次
在这里插入图片描述
在这里插入图片描述

如果停掉其中一个服务节点,那么就会导致33%的请求会失败。这个问题需要熔断器来解决,或者修改注册中心的配置,剔除失效的服务节点,后面写好了再来补充

本次demo知识点总结

1、服务的注册发现与消费至少三个模块,分别为注册中心。服务提供者。服务消费者。依次按顺序启动。
2、可以对注册中心以及服务提供者分别进行负载均衡。通过配置文件修改端口即可实现。
3、服务消费者对服务的调用消费:Ribbon+RestTemplate是一种客户端负载均衡的消费服务的方式,还有一种消费方式:feign,也是基于ribbon实现需要自己创建一个接口注入到Beans,并且feign集成了ribbon,结合了eureka,默认实现了负载均衡。
4、关于注解@EnableEurekaClient 不加也可以,应该是新版cloud的特性,个人不太确定,没找到官方解释。源码注释也说是可选的。个人认为是通过配置文件生效的。
5、yml中配置的信息,注册中心指定注册中心的地址,服务提供者注册到注册中心指定的地址完成服务注册,服务消费者指定注册中心的地址用来获取服务。
6、俩个注解:@EnableDiscoveryClient和@EnableEurekaClient的效果一样,用哪个取决于用什么注册中心,如果选用的注册中心是eureka,那么就推荐@EnableEurekaClient,如果是其他的注册中心,那么推荐使用@EnableDiscoveryClient【但是这吊玩意可选的。。】
7、多个服务停止一个之后,可以通过命令向eureka发送删除指令剔除停止的服务。或者等待eureka自动检查去剔除。否则会继续请求停止的服务报错{http://localhost:8770/eureka/apps/Eureka-Service:8773}
8、两种消费服务的区别
Ribbon+RestTemplate: Ribbon是一个负载均衡客户端,可以很好的控制htt和tcp的一些行为。
Feign: Feign 采用的是基于接口的注解,使用起来就好像在调用自己本地模块的服务似的。并且Feign 整合了ribbon

未完待续——如果看到这里了,(●'◡'●)该去点赞了啊喂

有空写完其他的服务相关的再来补充,啥玩意路由啊,断路器啊,消息总线啊,服务链路啊啥的。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值