【技术框架·SpringCloud】笔记记录

目录

  • 一、学习前言
    • 目的
    • 项目
      • 01:api-provide
        • pom.xml
        • ProvideApplication.java
        • TestCtrl.java
        • application.properties
        • 访问结果
      • 02:api-consumer
        • pom.xml
        • ConsumerApplication.java
        • RestTemplateConfig.java
        • TestRCtrl.java
        • application.properties
        • 访问结果
    • 步骤
      • 了解基本概念和架构:
      • 掌握Spring Boot的基础知识:
      • 学习Spring Cloud的组件:
      • 练习实战:
      • 持续学习和实践:
  • 二、了解基本概念和架构
    • 说明
    • 理论
      • 基本概念和架构
      • 对中小企业的缺点
      • 某些项目场景下的缺点
    • 项目 【Eureka】注册与发现
      • 父级工程 cloud-parent
        • pom.xml
      • 子模块工程 eureka-server
        • pom.xml
        • application.properties
        • application.yml
        • EurekaServerApplication.java
        • 访问
      • 子模块工程 eureka-client-provide
        • pom.xml
        • application.properties
        • application.yml
        • EurekaClientProvideApplication.java
        • TestCtrl.java
        • 访问
    • 项目 【Eureka】Ribbon 和 Feign 消费
      • 父级工程 cloud-parent
        • pom.xml
      • 子模块工程 eureka-client-c-ribbon
        • pom.xml
        • application.properties
        • application.yml
        • EurekaClientCRibbonApplication.java
        • TestCtrl.java
        • RestTemplateConfig.java
        • 访问

一、学习前言

为了解决某些问题,一些框架和库应运而生,例如Spring Cloud和Swagger等。这些工具提供了更安全、更一致和更易于使用的API开发方式,使得服务提供者和消费者能够更加高效地协作。

目的

Java传统服务提供和消费直接使用 Rest 存在一些缺陷,其中包括:

  • 缺乏类型安全:

    Restful API通常使用JSON或XML等格式来序列化数据,这些格式是文本格式,不包含类型信息。这使得在编写服务提供者和消费者时 -容易犯类型错误- ,从而导致运行时错误。

  • 缺乏编解码器:

    Restful API通常需要使用HTTP协议来通信,而HTTP协议是无状态协议,这意味着它不保留任何关于请求或响应的状态信息。因此,服务提供者和消费者需要使用 -编解码器- 来序列化和反序列化请求和响应,这增加了开发的复杂性。

  • 缺乏安全性:

    Restful API通常使用HTTP协议进行通信,而HTTP协议是明文协议,不提供任何安全性保障。因此,服务提供者和消费者需要自己实现安全性措施,例如使用OAuth或JWT等 -身份验证机制- 来保护API。

  • 缺乏一致性:

    由于Restful API -没有规定数据结构-,因此不同的服务提供者可能使用不同的数据格式和API端点,这使得服务消费者很难与多个服务提供者进行交互。此外,如果服务提供者改变了API端点或数据格式,消费者需要相应地修改代码,这增加了开发和维护的复杂性。

项目

回顾传统项目

普通服务提供者 - api-provide

普通服务消费者 - api-consumer

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kF8g0cMM-1687704560577)(img/image-20230625050357083.png)]

01:api-provide

模拟具备各种API功能的项目 【maven】

这是个简单项目,接口未使用 身份验证机制、规定数据结构等

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0modelVersion> <parent> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-parentartifactId> <version>2.7.12version> <relativePath/> parent> <groupId>com.devgroupId> <artifactId>api-provideartifactId> <version>0.0.1-SNAPSHOTversion> <name>api-providename> <description>Demo project for Spring Bootdescription>
	<properties>
		<java.version>1.8java.version>
	properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-webartifactId>
		dependency>

		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-devtoolsartifactId>
			<scope>runtimescope>
			<optional>trueoptional>
		dependency>
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-testartifactId>
			<scope>testscope>
		dependency>
	dependencies>

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

project>

ProvideApplication.java

启动类

package com.dev.apiprovide;

import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ProvideApplication {

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

}

TestCtrl.java

package com.dev.apiprovide.ctrl;

import java.util.HashMap; import java.util.Map; import org.springframework.util.ObjectUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController;

@RestController()
@RequestMapping("test")
public class TestCtrl{

    @RequestMapping(value = "api", method = RequestMethod.GET)
    public Map<String, Object> api(String data){
        Map<String, Object> resMap = new HashMap<>();

        if(ObjectUtils.isEmpty(data)){
            resMap.put("code", 500);
            resMap.put("msg", "is null");
        } else {
            resMap.put("code", 200);
            resMap.put("msg", "success");
        }

        return resMap;
    }

}

application.properties

server.port= 18081

访问结果

【技术框架·SpringCloud】笔记记录_第1张图片

02:api-consumer

模拟具使用API功能的项目 【maven】

这是个简单项目,使用http客户端直接调用访问。

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0modelVersion> <parent> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-parentartifactId> <version>2.7.12version> <relativePath/>  parent> <groupId>com.devgroupId> <artifactId>api-consumerartifactId> <version>0.0.1-SNAPSHOTversion> <name>api-consumername> <description>Demo project for Spring Bootdescription>
	<properties>
		<java.version>1.8java.version>
	properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-webartifactId>
		dependency>
		<dependency>
			<groupId>org.apache.httpcomponentsgroupId>
			<artifactId>httpclientartifactId>
		dependency>

		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-devtoolsartifactId>
			<scope>runtimescope>
			<optional>trueoptional>
		dependency>
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-testartifactId>
			<scope>testscope>
		dependency>
	dependencies>

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

project>

ConsumerApplication.java

启动类

package com.dev.apiconsumer;

import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ConsumerApplication {

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

}

RestTemplateConfig.java

rest 工具配置

package com.dev.apiconsumer.cfg;

import org.apache.http.client.HttpClient; import org.apache.http.conn.HttpClientConnectionManager; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {
    
    /**
     * http连接管理器
     * @return
     */
    @Bean("cdac_rtc_pgcm")
    public HttpClientConnectionManager poolingHttpClientConnectionManager() {
        /*// 注册http和https请求
        Registry registry = RegistryBuilder.create()
                .register("http", PlainConnectionSocketFactory.getSocketFactory())
                .register("https", SSLConnectionSocketFactory.getSocketFactory())
                .build();
        PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(registry);*/
        
        PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager();
        // 最大连接数
        poolingHttpClientConnectionManager.setMaxTotal(500);
        // 同路由并发数(每个主机的并发)
        poolingHttpClientConnectionManager.setDefaultMaxPerRoute(100);
        return poolingHttpClientConnectionManager;
    }
    
    /**
     * HttpClient
     * @param poolingHttpClientConnectionManager
     * @return
     */
    @Bean("cdac_rtc_hc")
    public HttpClient httpClient(@Autowired @Qualifier("cdac_rtc_pgcm")HttpClientConnectionManager poolingHttpClientConnectionManager) {
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        // 设置http连接管理器
        httpClientBuilder.setConnectionManager(poolingHttpClientConnectionManager);
        
        /*// 设置重试次数
        httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(3, true));*/
        
        // 设置默认请求头
        /*List
headers = new ArrayList<>(); headers.add(new BasicHeader("Connection", "Keep-Alive")); httpClientBuilder.setDefaultHeaders(headers);*/ return httpClientBuilder.build(); } /** * 请求连接池配置 * @param httpClient * @return */ @Bean("cdac_rtc_chq") public ClientHttpRequestFactory clientHttpRequestFactory(@Autowired @Qualifier("cdac_rtc_hc") HttpClient httpClient) { HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(); // httpClient创建器 clientHttpRequestFactory.setHttpClient(httpClient); // 连接超时时间/毫秒(连接上服务器(握手成功)的时间,超出抛出connect timeout) clientHttpRequestFactory.setConnectTimeout(5 * 1000); // 数据读取超时时间(socketTimeout)/毫秒(务器返回数据(response)的时间,超过抛出read timeout) clientHttpRequestFactory.setReadTimeout(10 * 1000); // 连接池获取请求连接的超时时间,不宜过长,必须设置/毫秒(超时间未拿到可用连接,会抛出org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool) clientHttpRequestFactory.setConnectionRequestTimeout(10 * 1000); return clientHttpRequestFactory; } /** * rest模板 * @return */ @Bean public RestTemplate restTemplate(@Autowired @Qualifier("cdac_rtc_chq")ClientHttpRequestFactory clientHttpRequestFactory) { // boot中可使用RestTemplateBuilder.build创建 RestTemplate restTemplate = new RestTemplate(); // 配置请求工厂 restTemplate.setRequestFactory(clientHttpRequestFactory); return restTemplate; } }

TestRCtrl.java

调用提供放接口的api

package com.dev.apiconsumer.ctrl;

import java.util.HashMap; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping("test")
public class TestRCtrl {
    
    @Autowired
    private RestTemplate restTemplate;

    // 提供者的IP:端口
    private String hostsUrl = "http://192.168.79.71:18081";

    @RequestMapping(value = "api", method = RequestMethod.GET)
    public Object api(String data){

        return restTemplate.getForObject(hostsUrl + "/test/api?data=null", HashMap.class, data);
    }

}

application.properties

server.port= 18082

访问结果

【技术框架·SpringCloud】笔记记录_第2张图片

步骤

了解基本概念和架构:

Spring Cloud是基于Spring Boot的实现,它提供了一系列的工具和组件,用于构建分布式系统。

掌握Spring Boot的基础知识:

Spring Boot是Spring Cloud的基础,它提供了一系列的工具和组件,用于构建独立的、可部署的微服务。

学习Spring Cloud的组件:

Spring Cloud提供了许多组件,例如服务注册中心、服务发现、负载均衡、断路器等,学习这些组件的使用和配置是非常重要的。

练习实战:

通过实战来加深对Spring Cloud的理解,例如实现一个简单的微服务、使用Spring Cloud实现服务注册和发现、使用Spring Cloud实现负载均衡等。

持续学习和实践:

Spring Cloud是一个不断发展的技术,需要不断学习和实践,以跟上它的步伐。参加技术交流会议、阅读官方文档和书籍、关注技术社区都是不错的学习途径。

二、了解基本概念和架构

说明

首先需要了解Spring Cloud的基本概念和架构。这可以通过阅读官方文档和在线教程来学习。

同时需掌握Spring Boot的基础知识,这是Spring Cloud的基础。可以通过学习Spring Boot的官方文档和在线教程来了解Spring Boot的基本概念、特性和使用方法。

然后,你需要学习Spring Cloud的组件,例如服务注册中心服务发现负载均衡断路器等。可以通过阅读官方文档、书籍和在线教程来学习这些组件的使用和配置方法。

在掌握Spring Cloud的基本概念、Spring Boot和Spring Cloud的组件后,你可以开始练习实战。例如,可以尝试实现一个简单的微服务、使用Spring Cloud实现服务注册和发现、使用Spring Cloud实现负载均衡等。通过实战来加深对Spring Cloud的理解和使用。

最后,需要持续学习和实践。参加技术交流会议、阅读官方文档和书籍、关注技术社区都是不错的学习途径。同时,需要保持耐心和坚持不懈的学习态度,遇到问题时可以寻求帮助他人或寻求社区的支持。

理论

基本概念和架构

是基于Spring Framework的一套全栈解决方案,用于构建分布式系统中的微服务架构。
Spring Cloud提供了丰富的组件和工具,可以快速地构建复杂的分布式系统。

它主要包括以下组件

  1. Eureka:提供 服务发现和注册 的功能,可以让微服务之间相互通信。

  2. Ribbon:提供 客户端负载均衡 的功能,可以将请求分发到多个服务实例中去。

  3. Feign:提供 声明式的HTTP 客户端,可以让调用远程服务的代码更加简洁。

  4. Hystrix:提供 熔断器 的功能,可以保证系统在出现故障时也能够正常运行。

  5. Zuul:提供 网关 的功能,可以将请求路由到不同的微服务实例中。

Spring Cloud的架构是由多个微服务组成的分布式系统。每个微服务都是一个独立的单元,可以独立进行开发、部署和管理。这些微服务通过Spring Cloud提供的各种组件和工具相互协作,最终形成一个完整的应用程序。

在这种架构下,每个微服务都有自己的数据存储和处理能力,可以独立进行水平扩展。通过服务注册与发现,微服务可以相互发现和调用,从而形成一个强大的分布式系统。

总之,Spring Cloud是一套全栈的微服务解决方案,它提供了丰富的组件和工具,可以帮助开发人员快速构建分布式系统。

对中小企业的缺点

  • 复杂性:

    Spring Cloud 是一个庞杂的框架,使用它需要具备一定的技术能力。对于一些中小型企业来说,他们可能没有足够的技术资源来使用这个框架。

  • 学习成本:

    由于 Spring Cloud 是一个庞杂的框架,学习它需要花费很长时间。中小型企业可能没有足够的时间和资源来培训他们的团队。

  • 部署复杂性:

    将 Spring Cloud 部署到生产环境中需要额外的努力和复杂性。中小型企业可能没有足够的资源来应对这个挑战。

  • 依赖性:

    Spring Cloud 依赖其他的 Spring 框架,如果应用程序不是基于 Spring 架构构建的,那么将它转换为 Spring Cloud 可能具有很高的成本和风险。

对于中小型企业来说,他们可能没有人力、时间和资源来应对这些缺点。
如果他们有足够的技术团队和时间做好调研和培训,那么使用 Spring Cloud 可以让他们更好地应对微服务架构。

某些项目场景下的缺点

  • 微服务过多,治理成本高:

    当系统中的微服务数量过多时,治理成本会变高,这会导致维护和管理的困难。

  • 分布式系统开发的成本高:

    分布式系统的开发需要考虑的问题比较多,例如容错、分布式事务等,这会导致开发的成本变高。

  • 重复工作:

    在某些情况下,由于微服务的拆分可能会导致重复的工作,这会影响开发效率和系统性能。

  • 复杂度增加:

    由于微服务的数量增加和分布式的特性,系统的复杂度会随之增加,这会导致调试和排查问题的难度增加。

  • 安全性考虑:

    在分布式系统中,需要考虑安全性问题,例如数据泄露、服务注入等,这需要投入更多的时间和精力来确保系统的安全性。

因此,在选择使用Spring Cloud时,需要根据具体的项目场景和需求来评估其优缺点,并制定合适的解决方案

项目 【Eureka】注册与发现

初步了解 Eureka 服务注册发现

父级工程 cloud-parent

【技术框架·SpringCloud】笔记记录_第3张图片

定义父工程,规范后面的项目模块依赖版本

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/maven-v4_0_0.xsd">
	<modelVersion>4.0.0modelVersion>
	<groupId>com.devgroupId>
	<artifactId>cloud-parentartifactId>
	<packaging>pompackaging>
	<version>1.0-SNAPSHOTversion>
	<name>spring cloud eureka 学习 name>
	<parent>
		<groupId>org.springframework.bootgroupId>
		<artifactId>spring-boot-starter-parentartifactId>
		<version>2.7.12version>
		<relativePath/>
	parent>

	<properties>
		<spring-cloud.version>2021.0.7spring-cloud.version>
	properties>

	<modules>
		<module>eureka-servermodule>
		<module>eureka-client-providemodule>
	modules>
project>

子模块工程 eureka-server

注意

当在存在权限的目录下运行可能导致以下消息出现

Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.202-b08 mixed mode):

"RMI TCP Accept-0" #15 daemon prio=5 os_prio=0 tid=0x00007f67fc6ae000 nid=0x4bfd runnable [0x00007f67d7540000]
   java.lang.Thread.State: RUNNABLE
        at java.net.PlainSocketImpl.socketAccept(Native Method)
        at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)
        at java.net.ServerSocket.implAccept(ServerSocket.java:545)
        at java.net.ServerSocket.accept(ServerSocket.java:513)
        at sun.management.jmxremote.LocalRMIServerSocketFactory$1.accept(LocalRMIServerSocketFactory.java:52)
        at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:405)
        at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:377)
        at java.lang.Thread.run(Thread.java:748)

这是 Eureka 服务端 项目

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0modelVersion>
	<parent>
		<groupId>com.devgroupId>
		<artifactId>cloud-parentartifactId>
		<version>1.0-SNAPSHOTversion>
	parent>
	<artifactId>eureka-serverartifactId>
	<version>0.0.1-SNAPSHOTversion>
	<name>服务端-eureka-servername>
	<properties>
		<java.version>1.8java.version>
	properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-thymeleafartifactId>
		dependency>
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-webartifactId>
		dependency>
		<dependency>
			<groupId>org.springframework.cloudgroupId>
			<artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
		dependency>

		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-testartifactId>
			<scope>testscope>
		dependency>
	dependencies>
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloudgroupId>
				<artifactId>spring-cloud-dependenciesartifactId>
				<version>${spring-cloud.version}version>
				<type>pomtype>
				<scope>importscope>
			dependency>
		dependencies>
	dependencyManagement>

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

project>

application.properties

server.port= 18090

application.yml

spring:
  freemarker:
    template-loader-path: classpath:/templates/
    prefer-file-system-access: false

eureka:
  instance:
    # 本机ip
    hostname: 127.0.0.1
  client:
    # 在 Eureka 注册
    registerWithEureka: false
    # 获取注册表
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

EurekaServerApplication.java

package com.dev.eurekaserv;

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

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {

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

}

访问

中文汉化自行百度

http://192.168.79.71:18090

sudo firewall-cmd --add-port=18090/tcp --permanent
sudo systemctl restart firewalld.service 

【技术框架·SpringCloud】笔记记录_第4张图片

子模块工程 eureka-client-provide

这是 Eureka 客户端 项目,参与服务提供

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0modelVersion>
	<parent>
		<groupId>com.devgroupId>
		<artifactId>cloud-parentartifactId>
		<version>1.0-SNAPSHOTversion>
	parent>
	<artifactId>eureka-serverartifactId>
	<version>0.0.1-SNAPSHOTversion>
	<name>服务端-eureka-servername>
	<properties>
		<java.version>1.8java.version>
	properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-thymeleafartifactId>
		dependency>
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-webartifactId>
		dependency>
		<dependency>
			<groupId>org.springframework.cloudgroupId>
			<artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
		dependency>

		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-testartifactId>
			<scope>testscope>
		dependency>
	dependencies>
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloudgroupId>
				<artifactId>spring-cloud-dependenciesartifactId>
				<version>${spring-cloud.version}version>
				<type>pomtype>
				<scope>importscope>
			dependency>
		dependencies>
	dependencyManagement>

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

project>

application.properties

server.port= 18091

application.yml

spring:
  application:
    name: api-eureka-provide

# https://docs.spring.io/spring-cloud-netflix/docs/current/reference/html/#service-discovery-eureka-clients
eureka:
  client:
    serviceUrl:
      defaultZone: http://192.168.79.71:18090/eureka/
    rest-template-timeout:
      connect-timeout: 5000
      connect-request-timeout: 8000
      socket-timeout: 10000

EurekaClientProvideApplication.java

package com.dev.eurekaclientprovide;

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

@SpringBootApplication
@EnableEurekaClient
public class EurekaClientProvideApplication {

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

}

TestCtrl.java

package com.dev.eurekaclientprovide.ctrl;

import java.util.HashMap;
import java.util.Map;

import org.springframework.http.MediaType;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController()
public class TestCtrl{

    @RequestMapping(value = "test/def", method = RequestMethod.GET)
    public Map<String, Object> def(String data){
        Map<String, Object> resMap = new HashMap<>();

        if(ObjectUtils.isEmpty(data)){
            resMap.put("code", 500);
            resMap.put("msg", "is null");
        } else {
            resMap.put("code", 200);
            resMap.put("msg", "success");
            resMap.put("data", data);
        }

        return resMap;
    }

    @RequestMapping(value = "test/json", method = RequestMethod.GET, produces = MediaType.APPLICATION_PROBLEM_JSON_VALUE)
    public Map<String, Object> json(String data){
        Map<String, Object> resMap = new HashMap<>();

        if(ObjectUtils.isEmpty(data)){
            resMap.put("code", 500);
            resMap.put("msg", "is null");
        } else {
            resMap.put("code", 200);
            resMap.put("msg", "success");
            resMap.put("data", data);
        }

        return resMap;
    }

}

访问

http://192.168.79.71:18091/test/def

http://192.168.79.71:18091/test/json

sudo firewall-cmd --add-port=18091/tcp --permanent && sudo systemctl restart firewalld.service 

项目 【Eureka】Ribbon 和 Feign 消费

父级工程 cloud-parent

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/maven-v4_0_0.xsd">
	<modelVersion>4.0.0modelVersion>
	<groupId>com.devgroupId>
	<artifactId>cloud-parentartifactId>
	<packaging>pompackaging>
	<version>1.0-SNAPSHOTversion>
	<name>spring cloud eureka 学习 name>
	<parent>
		<groupId>org.springframework.bootgroupId>
		<artifactId>spring-boot-starter-parentartifactId>
		<version>2.7.12version>
		<relativePath/>
	parent>

	<properties>
		<spring-cloud.version>2021.0.7spring-cloud.version>
	properties>

	<modules>
      <module>eureka-servermodule>
      <module>eureka-client-providemodule>
	  <module>eureka-client-p-ribbonmodule>
  modules>
project>

子模块工程 eureka-client-c-ribbon

一个对外项目,简单演示如何进入注册中心消费

当有人找自己,但自己没有服务,就问服务中心有没有符合条件的代为帮忙

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>
	<parent>
		<groupId>com.devgroupId>
		<artifactId>cloud-parentartifactId>
		<version>1.0-SNAPSHOTversion>
	parent>
    <artifactId>eureka-client-c-ribbonartifactId>
	<version>0.0.1-SNAPSHOTversion>
    <packaging>jarpackaging>
	<name>客户端-Eureka-p-ribbon 消费name>
    <properties>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
        <start-class>com.dev.Appstart-class>
        <java.version>1.8java.version>
        <lombok.version>1.14.8lombok.version>
        <log4jdbc.log4j2.version>1.16log4jdbc.log4j2.version>
        <rest.assured.version>2.3.3rest.assured.version>
    properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
		<dependency>
			<groupId>org.springframework.cloudgroupId>
			<artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
		dependency>

        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <version>${lombok.version}version>
            <scope>providedscope>
        dependency>
        <dependency>
            <groupId>org.bgee.log4jdbc-log4j2groupId>
            <artifactId>log4jdbc-log4j2-jdbc4.1artifactId>
            <version>${log4jdbc.log4j2.version}version>
        dependency>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
        <dependency>
            <groupId>com.jayway.restassuredgroupId>
            <artifactId>rest-assuredartifactId>
            <version>${rest.assured.version}version>
            <scope>testscope>
        dependency>
    dependencies>
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloudgroupId>
				<artifactId>spring-cloud-dependenciesartifactId>
				<version>${spring-cloud.version}version>
				<type>pomtype>
				<scope>importscope>
			dependency>
		dependencies>
	dependencyManagement>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.bootgroupId>
				<artifactId>spring-boot-maven-pluginartifactId>
			plugin>
		plugins>
	build>

project>

application.properties

server.port= 18092

# 设置最大内存
spring.datasource.tomcat.max-active= 300
# 设置最小内存
spring.datasource.tomcat.min-idle= 128

s.eureka.host= 192.168.79.71
s.eureka.port= 18090
s.provide.name= api-eureka-provide

application.yml

spring:
  application:
    name: eureka-client-c-ribbon

# https://docs.spring.io/spring-cloud-netflix/docs/current/reference/html/#service-discovery-eureka-clients
eureka:
  client:
    serviceUrl:
      defaultZone: http://${s.eureka.host}:${s.eureka.port}/eureka/
    rest-template-timeout:
      connect-timeout: 5000
      connect-request-timeout: 8000
      socket-timeout: 10000

EurekaClientCRibbonApplication.java

package com.dev.eurekaclientcribbon;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class EurekaClientCRibbonApplication {

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

TestCtrl.java

package com.dev.eurekaclientcribbon.ctrl;

import java.util.HashMap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController()
@PropertySource("classpath:application.properties")
public class TestCtrl{

    @Autowired
    RestTemplate restTemplate;

    // 提供者
    @Value("${s.provide.name}")
    private String hostsUrl;

    @RequestMapping(value = "test/def", method = RequestMethod.GET)
    public Object def(String data){
        return restTemplate.getForObject("http://" +hostsUrl + "/test/def?data={data}", HashMap.class, data);
    }

    @RequestMapping(value = "test/json", method = RequestMethod.GET, produces = MediaType.APPLICATION_PROBLEM_JSON_VALUE)
    public Object json(String data){
        return restTemplate.getForObject("http://" +hostsUrl + "/test/json?data={data}", HashMap.class, data);
    }

}

RestTemplateConfig.java

package com.dev.eurekaclientcribbon.cfg;

import org.apache.http.client.HttpClient;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {
    
    /**
     * http连接管理器
     * @return
     */
    @Bean("cdac_rtc_pgcm")
    public HttpClientConnectionManager poolingHttpClientConnectionManager() {
        /*// 注册http和https请求
        Registry registry = RegistryBuilder.create()
                .register("http", PlainConnectionSocketFactory.getSocketFactory())
                .register("https", SSLConnectionSocketFactory.getSocketFactory())
                .build();
        PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(registry);*/
        
        PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager();
        // 最大连接数
        poolingHttpClientConnectionManager.setMaxTotal(500);
        // 同路由并发数(每个主机的并发)
        poolingHttpClientConnectionManager.setDefaultMaxPerRoute(100);
        return poolingHttpClientConnectionManager;
    }
    
    /**
     * HttpClient
     * @param poolingHttpClientConnectionManager
     * @return
     */
    @Bean("cdac_rtc_hc")
    public HttpClient httpClient(@Autowired @Qualifier("cdac_rtc_pgcm")HttpClientConnectionManager poolingHttpClientConnectionManager) {
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        // 设置http连接管理器
        httpClientBuilder.setConnectionManager(poolingHttpClientConnectionManager);
        
        /*// 设置重试次数
        httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(3, true));*/
        
        // 设置默认请求头
        /*List
headers = new ArrayList<>(); headers.add(new BasicHeader("Connection", "Keep-Alive")); httpClientBuilder.setDefaultHeaders(headers);*/ return httpClientBuilder.build(); } /** * 请求连接池配置 * @param httpClient * @return */ @Bean("cdac_rtc_chq") public ClientHttpRequestFactory clientHttpRequestFactory(@Autowired @Qualifier("cdac_rtc_hc") HttpClient httpClient) { HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(); // httpClient创建器 clientHttpRequestFactory.setHttpClient(httpClient); // 连接超时时间/毫秒(连接上服务器(握手成功)的时间,超出抛出connect timeout) clientHttpRequestFactory.setConnectTimeout(5 * 1000); // 数据读取超时时间(socketTimeout)/毫秒(务器返回数据(response)的时间,超过抛出read timeout) clientHttpRequestFactory.setReadTimeout(10 * 1000); // 连接池获取请求连接的超时时间,不宜过长,必须设置/毫秒(超时间未拿到可用连接,会抛出org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool) clientHttpRequestFactory.setConnectionRequestTimeout(10 * 1000); return clientHttpRequestFactory; } /** * rest模板 * @return */ @Bean("restTemplate") @Primary @LoadBalanced public RestTemplate restTemplate(@Autowired @Qualifier("cdac_rtc_chq")ClientHttpRequestFactory clientHttpRequestFactory) { // boot中可使用RestTemplateBuilder.build创建 RestTemplate restTemplate = new RestTemplate(); // 配置请求工厂 restTemplate.setRequestFactory(clientHttpRequestFactory); return restTemplate; } }

访问

http://192.168.79.71:18092/test/def

http://192.168.79.71:18092/test/json

sudo firewall-cmd --add-port=18092/tcp --permanent && sudo systemctl restart firewalld.service 

【技术框架·SpringCloud】笔记记录_第5张图片

你可能感兴趣的:(MY-技术学习,spring,cloud,笔记,java)