SpringCloud学习笔记(五、视图微服务-RIBBON)

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
注册配置 MSE Nacos/ZooKeeper,182元/月
MSE Nacos/ZooKeeper 企业版试用,1600元额度,限量50份
简介: SpringCloud学习笔记(五、视图微服务-RIBBON)

RIBBON是什么?

前面已经做好了数据微服务,现在是时候整个视图微服务访问前面注册好的数据微服务了。 springcloud 提供了两种方式,一种是 Ribbon,一种是 Feign。

Ribbon 是使用 restTemplate 进行调用,并进行客户端负载均衡。 什么是客户端负载均衡呢? 在前面 注册数据微服务  里,注册了8001和8002两个微服务, Ribbon 会从注册中心获知这个信息,然后由 Ribbon  这个客户端自己决定是调用哪个,这个就叫做客户端负载均衡。

Feign 是什么呢? Feign 是对 Ribbon的封装,调用起来更简单。

建立子项目

创建子项目 product-view-service-ribbon:

image.png

pom.xml

spring-cloud-starter-netflix-eureka-client: eureka 客户端

spring-boot-starter-web: springmvc

spring-boot-starter-thymeleaf: thymeleaf 做服务端渲染

<?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>springcloud</artifactId>
        <groupId>edu.hpu.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>product-view-service-ribbon</artifactId>
    <name>product-view-service-ribbon</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>  <!--eureka 客户端-->
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>  <!--SpringMvc-->
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
    </dependencies>
</project>
实体类
package edu.hpu.springcloud.pojo;
public class Product {
    private int id;
    private String name;
    private int price;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getPrice() {
        return price;
    }
    public void setPrice(int price) {
        this.price = price;
    }
    public Product(int id, String name, int price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }
    public Product() {
    }
}
Ribbon 客户端

Ribbon 客户端, 通过 restTemplate 访问 http://PRODUCT-DATA-SERVICE/products , 而 product-data-service 既不是域名也不是ip地址,而是 数据服务在 eureka 注册中心的名称。

看一下注册中心:

image.png上面那个地址只指定了服务,没有指定端口号。

package edu.hpu.springcloud.client;
import edu.hpu.springcloud.pojo.Product;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import java.util.List;
//Ribbon 客户端
@Component
public class ProductClientRibbon {
    @Autowired
    RestTemplate restTemplate;
    public List<Product> listProcucts(){
        return restTemplate.getForObject("http://PRODUCT-DATA-SERVICE/products",List.class);
    }
}
服务层

服务层数据从客户端获取

package edu.hpu.springcloud.service;
import edu.hpu.springcloud.client.ProductClientRibbon;
import edu.hpu.springcloud.pojo.Product;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class ProductService {
    @Autowired
    ProductClientRibbon productClientRibbon;
    public List<Product> listProducts(){
        return productClientRibbon.listProcucts();   //从productClientRibbon中获得数据服务
    }
}
控制层
package edu.hpu.springcloud.controller;
import edu.hpu.springcloud.pojo.Product;
import edu.hpu.springcloud.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
public class ProductController {
    @Autowired
    ProductService productService;
    @RequestMapping("/products")
    public Object products(Model m){
        List<Product> ps=productService.listProducts();
        m.addAttribute("ps",ps);
        return "products";
    }
}
视图

视图采用thymeleaf:

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>products</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <style>
        table {
            border-collapse:collapse;
            width:400px;
            margin:20px auto;
        }
        td,th{
            border:1px solid gray;
        }
    </style>
</head>
<body>
<div class="workingArea">
    <table>
        <thead>
        <tr>
            <th>id</th>
            <th>产品名称</th>
            <th>价格</th>
        </tr>
        </thead>
        <tbody>
        <tr th:each="p: ${ps}">
            <td th:text="${p.id}"></td>
            <td th:text="${p.name}"></td>
            <td th:text="${p.price}"></td>
        </tr>
        </tbody>
    </table>
</div>
</body>
</html>
配置

application.yml,eureka server 的地址,以及自己的名称。 另外是一些 thymeleaf 的默认配置

eureka:
  clg: UTF-8
    content-type: text/html
    mode: HTML5ient:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
spring:
  application:
    name: product-view-service-ribbon
  thymeleaf:
    cache: false
    prefix: classpath:/templates/
    suffix: .html
    encodin
启动类

ProductDataServiceApplication,

启动类, 注解多了个 @EnableDiscoveryClient, 表示用于发现eureka 注册中心的微服务。

还多了个 RestTemplate,就表示用 restTemplate 这个工具来做负载均衡

   @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

在ribbon客户端中使用了这个RestTemplate.

package edu.hpu.springcloud;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.NetUtil;
import cn.hutool.core.util.NumberUtil;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import java.util.Scanner;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@SpringBootApplication
@EnableEurekaClient
public class ProductDataServiceApplication {
    public static void main(String[] args) {
        int port = 0;
        int defaultPort = 8003;
        Future<Integer> future = ThreadUtil.execAsync(() ->{
            int p = 0;
            System.out.println("请于5秒钟内输入端口号, 推荐  8001 、 8002  或者  8003,超过5秒将默认使用 " + defaultPort);
            Scanner scanner = new Scanner(System.in);
            while(true) {
                String strPort = scanner.nextLine();
                if(!NumberUtil.isInteger(strPort)) {
                    System.err.println("只能是数字");
                    continue;
                }
                else {
                    p = Convert.toInt(strPort);
                    scanner.close();
                    break;
                }
            }
            return p;
        });
        try{
            port=future.get(5, TimeUnit.SECONDS);
        }
        catch (InterruptedException | ExecutionException | TimeoutException e){
            port = defaultPort;
        }
        if(!NetUtil.isUsableLocalPort(port)) {
            System.err.printf("端口%d被占用了,无法启动%n", port );
            System.exit(1);
        }
        new SpringApplicationBuilder(ProductDataServiceApplication.class).properties("server.port=" + port).run(args);
    }
}
运行访问

image.png

调用图示

这里面三个角色,注册中心、服务提供者、服务消费者,数据微服务作为服务提供者,视图微服务作为服务消费者。

1、 首先数据微服务和视图微服务都被 eureka 管理起来了。

2、 数据服务是由三个实例的集群组成的,端口分别是 8001 , 8002,8003。

3、视图微服务通过 注册中心调用微服务, 然后负载均衡到 8001 、8002或者8003端口的应用上。

image.png

错误

1、springCloud com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused: connect

在默认设置下,Eureka服务注册中心也会将自己作为客户端来尝试注册它自己,所以我们需要禁用它的客户端注册行为。

禁止方式如下:在application.properties配置文件中增加以下内容

eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false

.yml也差不多,写的时候注意级别就行了。

2、低级错误:注册中心和数据微服务没启动

中间关了IJ,直接启动视图微服务,爆了一堆错,一想,是注册中心和数据微服务没启动,它向谁请求、调用谁去。

3、java.lang.IllegalStateException: No instances available for PRODUCT-DATA-SERVICE

找不到这个实例,我们看一下注册中心,看看数据微服务叫什么名字。

image.png似乎也没什么错,不算了,直接给它粘贴到客户端。OK。

4、java.net.ConnectException: Connection refused: connect

刷新页面的时候发现报了这么个错误,负载均衡一到数据微服务8002这个端口的时候就报错,似乎是被占用了吧,我又注册个端口为8003的数据微服务,这个端口倒是没有问题。

image.png

参考:

【1】、http://how2j.cn/k/springcloud/springcloud-ribbon/2040.html#nowhere

【2】、https://blog.csdn.net/qq_39930369/article/details/87616077

【3】、https://www.cnblogs.com/zmblog/p/8777878.html


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
目录
相关文章
|
1月前
|
监控 Java API
Spring Boot 3.2 结合 Spring Cloud 微服务架构实操指南 现代分布式应用系统构建实战教程
Spring Boot 3.2 + Spring Cloud 2023.0 微服务架构实践摘要 本文基于Spring Boot 3.2.5和Spring Cloud 2023.0.1最新稳定版本,演示现代微服务架构的构建过程。主要内容包括: 技术栈选择:采用Spring Cloud Netflix Eureka 4.1.0作为服务注册中心,Resilience4j 2.1.0替代Hystrix实现熔断机制,配合OpenFeign和Gateway等组件。 核心实操步骤: 搭建Eureka注册中心服务 构建商品
353 3
|
11天前
|
监控 安全 Java
Spring Cloud 微服务治理技术详解与实践指南
本文档全面介绍 Spring Cloud 微服务治理框架的核心组件、架构设计和实践应用。作为 Spring 生态系统中构建分布式系统的标准工具箱,Spring Cloud 提供了一套完整的微服务解决方案,涵盖服务发现、配置管理、负载均衡、熔断器等关键功能。本文将深入探讨其核心组件的工作原理、集成方式以及在实际项目中的最佳实践,帮助开发者构建高可用、可扩展的分布式系统。
49 1
|
18天前
|
jenkins Java 持续交付
使用 Jenkins 和 Spring Cloud 自动化微服务部署
随着单体应用逐渐被微服务架构取代,企业对快速发布、可扩展性和高可用性的需求日益增长。Jenkins 作为领先的持续集成与部署工具,结合 Spring Cloud 提供的云原生解决方案,能够有效简化微服务的开发、测试与部署流程。本文介绍了如何通过 Jenkins 实现微服务的自动化构建与部署,并结合 Spring Cloud 的配置管理、服务发现等功能,打造高效、稳定的微服务交付流程。
使用 Jenkins 和 Spring Cloud 自动化微服务部署
|
22天前
|
Kubernetes Java 微服务
Spring Cloud 微服务架构技术解析与实践指南
本文档全面介绍 Spring Cloud 微服务架构的核心组件、设计理念和实现方案。作为构建分布式系统的综合工具箱,Spring Cloud 为微服务架构提供了服务发现、配置管理、负载均衡、熔断器等关键功能的标准化实现。本文将深入探讨其核心组件的工作原理、集成方式以及在实际项目中的最佳实践,帮助开发者构建高可用、可扩展的分布式系统。
218 0
|
3月前
|
负载均衡 Java API
基于 Spring Cloud 的微服务架构分析
Spring Cloud 是一个基于 Spring Boot 的微服务框架,提供全套分布式系统解决方案。它整合了 Netflix、Zookeeper 等成熟技术,通过简化配置和开发流程,支持服务发现(Eureka)、负载均衡(Ribbon)、断路器(Hystrix)、API网关(Zuul)、配置管理(Config)等功能。此外,Spring Cloud 还兼容 Nacos、Consul、Etcd 等注册中心,满足不同场景需求。其核心组件如 Feign 和 Stream,进一步增强了服务调用与消息处理能力,为开发者提供了一站式微服务开发工具包。
492 0
|
7月前
|
传感器 监控 安全
智慧工地云平台的技术架构解析:微服务+Spring Cloud如何支撑海量数据?
慧工地解决方案依托AI、物联网和BIM技术,实现对施工现场的全方位、立体化管理。通过规范施工、减少安全隐患、节省人力、降低运营成本,提升工地管理的安全性、效率和精益度。该方案适用于大型建筑、基础设施、房地产开发等场景,具备微服务架构、大数据与AI分析、物联网设备联网、多端协同等创新点,推动建筑行业向数字化、智能化转型。未来将融合5G、区块链等技术,助力智慧城市建设。
350 1
|
SpringCloudAlibaba API 开发者
新版-SpringCloud+SpringCloud Alibaba
新版-SpringCloud+SpringCloud Alibaba
|
6月前
|
负载均衡 Dubbo Java
Spring Cloud Alibaba与Spring Cloud区别和联系?
Spring Cloud Alibaba与Spring Cloud区别和联系?
|
7月前
|
人工智能 SpringCloudAlibaba 自然语言处理
SpringCloud Alibaba AI整合DeepSeek落地AI项目实战
在现代软件开发领域,微服务架构因其灵活性、可扩展性和模块化特性而受到广泛欢迎。微服务架构通过将大型应用程序拆分为多个小型、独立的服务,每个服务运行在其独立的进程中,服务与服务间通过轻量级通信机制(通常是HTTP API)进行通信。这种架构模式有助于提升系统的可维护性、可扩展性和开发效率。
2297 2