SpringBoot集成SpringCloud牛刀小试&Eureka单机版&Eureka集群搭建

微服务

特点

1.由一系列小服务组成

2.可以独立的运行在自己的计算机进程(服务于服务之间互不影响)

3.每个服务可以独立部署

4.服务都是基于分布式管理

定义

微服务就是一系列服务功能组成,能单独泡在自己的进程中,每个服务独立开发,独立运行,分布式管理

单体架构

优点

容易测试

容易部署

缺点

开发效率低

代码维护难

部署不灵活(必须的全部项目开发好才能部署)

稳定性不高

扩展性不高

SpringCloud概述

SpringCloud是一个涵盖多个子项目的开发工具集,集合了众多的开源框架,利用;了SpringBoot的开发便利性,实现了很多功能,如服务注册,服务注册发现,负载均衡等,SpringCloud在整合过程中主要是针对于NetFlix(耐非)开元组件的封装。

NetFlix是美国的一个在线视频网站,微服务业的翘楚,他是公认的大规模生产级微服务的接触实践者,NetFlix的开源组件已经在他大规模分布式微服务环境中警告多年的生产实战验证,因此spring cloud中很多组件都是基于NetFlix组件的封装。

官网:http://projects.spring.io/spring-cloud/

这里主要是针对springboot集成springcloud的相关配置
SpringBoot集成SpringCloud牛刀小试&Eureka单机版&Eureka集群搭建_第1张图片

1.负载均衡Ribbon基本原理以及模拟实现

Spring Cloud Ribbon 是一个基于Http和TCP的客服端负载均衡工具,它是基于Netflix Ribbon实现的。通过SpringCloud的自动配置使得项目可以自动的给RestTemplate添加拦截器,实现类似于上一节负载均衡的作用。

  • 1.实现HttpRequest,静态代理,重新确定主机名端口号
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class HostPort {
    private String host;//主机名
    private String port;//端口
}

package com.baizhi.loadbalance;


import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Random;

//静态代理,通过该类重新实现实际访问的端口与主机名
@Slf4j
public class UsertDefinedHttpRequest implements HttpRequest {
    //被代理的请求,源请求
    private HttpRequest request;
    //模拟端口主机名map与逻辑名的映射
    Map> resourceMap = null;

    //带参构造,为request,resourceMap赋值
    public UsertDefinedHttpRequest(HttpRequest request){
        this.request = request;
        resourceMap.put("USER_SERVICE", Arrays.asList(
                new HostPort("192.168.192.14","8989"),
                new HostPort("192.168.192.15","8989"),
                new HostPort("192.168.192.19","8989")
        ));
    }

    @Override
    //不变
    public String getMethodValue() {
        return request.getMethodValue();
    }

    @Override
    //主要是修改端口与主机名,并进行负载均衡
    public URI getURI() {
        //原来的URI
        URI originURI = request.getURI();
        //返回新的URI
        URI newURI = null;
        //拿到原始请求的主机名
        String uriHost = originURI.getHost();
        //如果访问的逻辑名是USER_SERVICE时
        if(resourceMap.containsKey(uriHost)){
            //拿到服务注册列表
            List hostPorts = resourceMap.get(uriHost);
            //随机访问哪一个服务
            HostPort newHostPort = hostPorts.get(new Random().nextInt(hostPorts.size()));
            //构建新的URI
            try {
                newURI = new URI(originURI.getScheme(),originURI.getUserInfo(),newHostPort.getHost(),Integer.valueOf(newHostPort.getPort()),originURI.getPath(),originURI.getQuery(),originURI.getFragment());
            } catch (URISyntaxException e) {
                e.printStackTrace();
            }

        }else{
            newURI = originURI;//否则就不变动URI
        }
        log.info("=====新的URI:" + newURI);
        return newURI;
    }

    @Override
    //不变
    public HttpHeaders getHeaders() {
        return request.getHeaders();
    }
}

  • 2.实现ClientHttpRequestInterceptor自定义拦截器,覆盖拦截请求
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;

import java.io.IOException;

//自定义拦截器,拦截
public class UserDefinedLoadbanlanceInterceptor implements ClientHttpRequestInterceptor {
    @Override
    public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes, ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
        return clientHttpRequestExecution.execute(new UsertDefinedHttpRequest(httpRequest),bytes);
    }
}
  • 3.添加自定义拦截器
@SpringBootApplication
public class WebApplication {
    public static void main(String[] args) {
        SpringApplication.run(WebApplication.class,args);
    }

    @Bean
    public RestTemplate restTemplate(){
        RestTemplate restTemplate = new RestTemplate();
        //添加拦截器
        restTemplate.getInterceptors().add(new UserDefinedLoadbanlanceInterceptor())
        return restTemplate;
    }
}
  • 4.测试
  • 打包上传到三台虚拟机上
  • 测试代码
import com.baizhi.UserWebApplication;
import com.baizhi.entities.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.client.RestTemplate;

@SpringBootTest(classes ={UserWebApplication.class} )
@RunWith(SpringRunner.class)
public class RestTemplateTests {
    @Autowired
    private RestTemplate restTemplate;
    private String prefix="http://USER-SERVICE";
    @Test
    public void testQuertUserById(){
        for(int i=0;i<100;i++){
            String url=prefix+"/user/restUserManager/queryUserById?id={id}";
            User user = restTemplate.getForObject(url, User.class, 83);
        }
    }
}

Eureka服务

Spring Cloud Eureka 是 Spring Cloud Netflix 微服务套件中的一部分, 它基于 Netflix Eureka 做了二次封装, 主要负责完成微服务架构中的服务治理功能。 Spring Cloud 通过为Eureka 增加了 Spring Boot 风格的自动化配置,我们只需通过简单引入依赖和注解配置就能让 Spring Boot构建的微服务应用轻松地与 Eureka 服务治理体系进行整合。

既是一个web实例,又是一个client,抓取其他服务实例
SpringBoot集成SpringCloud牛刀小试&Eureka单机版&Eureka集群搭建_第2张图片

Eureka单机

  • 1.pom.xml

        org.springframework.boot
        spring-boot-starter-parent
        2.1.5.RELEASE
    

    
        
            
                org.springframework.cloud
                spring-cloud-dependencies
                Greenwich.SR1
                pom
                import
            
        
    

    
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-server
        
    
  • 2.application.properties
# 服务基本配置
server.port=9999

# 配置Eureka服务注册中心

# 服务实例的运行时主机名
eureka.instance.hostname=localhost

#注册的服务必须每隔60秒发送一次心跳,否则就会从服务列表中剔除
eureka.server.expected-client-renewal-interval-seconds=60
#时隔1000ms检测一次有没有宕机的实例
eureka.server.eviction-interval-timer-in-ms=1000
# 注册中心服务相关配置 ,如果收到的心跳低于期望心跳85%,则注册中心会进入`自我保护机制` - 不删除注册中心认定失效的节点
eureka.server.renewal-percent-threshold=0.85
#隔多长时间同步一次,是否达到阈值
eureka.server.wait-time-in-ms-when-sync-empty=10000

# 关闭Eureka自我注册和抓取功能
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false

必须配置eureka.instance.hostname否则Eureka会尝试自我注册

  • 3.启动入口类函数
@SpringBootApplication
@EnableEurekaServer //开启服务注解
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class,args);
    }
}
  • 4.访问浏览器查看eureka服务状态
    SpringBoot集成SpringCloud牛刀小试&Eureka单机版&Eureka集群搭建_第3张图片

一分钟期望收1 * 0.85 = 0次心跳—阈值为0
目前没有实例注册,所以也是0

  • 5.配置说明
    配置 说明 默认参数
    eureka.server.enable-self-preservation Eureka自我保护机制 true
    eureka.server.eviction-interval-timer-in-ms Eureka剔除故障节点时间间隔 60秒
    eureka.server.renewal-percent-threshold Eureka租约计算阈值 0.85
    eureka.client.register-with-eureka 是否注册到Eureka上 true
    eureka.client.fetch-registry 是否从Eureka上更新列表信息 true
    eureka.instance.hostname Eureka微服务实例的主机名 -

注册服务

  • 1.pom.xml

  
    
      org.springframework.cloud
      spring-cloud-dependencies
      Greenwich.SR1
      pom
      import
    
  



  org.springframework.boot
  spring-boot-starter-actuator


  org.springframework.cloud
  spring-cloud-starter-netflix-eureka-client

  • 2.application.properties
#服务实例主机名
spring.application.name=USER-SERVICE
#服务实例id
eureka.instance.instance-id=001
#是否优先显示地址
eureka.instance.prefer-ip-address=true
#20秒没法送心跳,就认定出问题了
eureka.instance.lease-expiration-duration-in-seconds=20
#10秒发一个心跳
eureka.instance.lease-renewal-interval-in-seconds=10
#注册服务
eureka.client.register-with-eureka=true
eureka.client.healthcheck.enabled=true
#不关心eureka自身变化
eureka.client.fetch-registry=false
#往哪里注册
eureka.client.service-url.defaultZone=http://localhost:9999/eureka/

spring:
  application:
    # 服务实例的主机名
    name: USER-SERVICE
eureka:
  instance:
    instance-id: 001
    prefer-ip-address: true
    lease-expiration-duration-in-seconds: 20
    lease-renewal-interval-in-seconds: 10
    # 向Eureka注册中心注册服务
  client:
    register-with-eureka: true
    fetch-registry: false
    service-url:
      defaultZone: http://localhost:9999/eureka/
  • 查看状态SpringBoot集成SpringCloud牛刀小试&Eureka单机版&Eureka集群搭建_第4张图片

使用服务–消费

因为默认Eureka中集成了Ribbon插件,因此主需要导入spring-cloud-starter-netflix-eureka-client即可。

  • 1.pom.xml
    
        
            
                org.springframework.cloud
                spring-cloud-dependencies
                Greenwich.SR1
                pom
                import
            
        
    
 
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-client
 
  • 2.application.properties
eureka.client.fetch-registry=true
eureka.client.register-with-eureka=false
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/

  • 3.入口类函数
@SpringBootApplication
public class WebApplication {
    public static void main(String[] args) {
        SpringApplication.run(WebApplication.class,args);
    }

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        RestTemplate restTemplate = new RestTemplate();
        //添加拦截器
        //restTemplate.getInterceptors().add(new UserDefinedLoadbanlanceInterceptor());
        return restTemplate;
    }
}
  • 4.测试类
import com.baizhi.WebApplication;
import com.baizhi.entities.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.client.RestTemplate;

@SpringBootTest(classes = WebApplication.class)
@RunWith(SpringRunner.class)
public class RestTemplateTests1 {
    @Autowired
    private RestTemplate restTemplate;
    @Test
    public void testQueryUserById(){
        String url="http://USER-SERVICE//user/restUserManager/queryUserById?id={id}";
        User user = restTemplate.getForObject(url, User.class,5);
        System.out.println(user);
    }
}

Eureka集群搭建

  • 1.pom.xml

        org.springframework.boot
        spring-boot-starter-parent
        2.1.5.RELEASE
    

    
        
            
                org.springframework.cloud
                spring-cloud-dependencies
                Greenwich.SR1
                pom
                import
            
        
    

    
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-server
        
    
    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    
  • 2.application-eureka-1.properties
server.port=1111

# 指定当前注册中心的服务名称
spring.application.name=eureka-registry

## 启用注册中心主动失效,并且每次主动失效检测间隔为5s 默认值60s
eureka.server.eviction-interval-timer-in-ms= 5000
## 设置eureka注册中心的响应更新时间
eureka.server.responseCacheUpdateIntervalMs=3000
eureka.server.responseCacheAutoExpirationInSeconds=60
eureka.server.expected-client-renewal-interval-seconds=60
eureka.server.renewal-percent-threshold=0.85
eureka.server.wait-time-in-ms-when-sync-empty=10000

## 配置注册中心的主机名
eureka.instance.instance-id = eureka-1
eureka.instance.hostname = 192.168.192.14
## 服务刷新时间配置,每隔这个时间会主动心跳一次
eureka.instance.lease-renewal-interval-in-seconds= 5
## 服务提供者被认定为丢失心跳超时,失效多久后被删除
eureka.instance.lease-expiration-duration-in-seconds=15

## 配置定时获取|抓取注册中心的数据时间
eureka.client.registry-fetch-interval-seconds= 5
eureka.client.instance-info-replication-interval-seconds= 5
## 配置集群中其他eureka实例,用于本eureka实例的注册方。
eureka.client.region=beijing
eureka.client.availability-zones.beijing=zone-2,zone-3
eureka.client.service-url.zone-2=http://192.168.192.15:1111/eureka/
eureka.client.service-url.zone-3=http://192.168.192.19:1111/eureka/
  • 3.application-eureka-2.properties
server.port=1111

# 指定当前注册中心的服务名称
spring.application.name=eureka-registry

## 启用注册中心主动失效,并且每次主动失效检测间隔为5s 默认值60s
eureka.server.eviction-interval-timer-in-ms= 5000
## 设置eureka注册中心的响应更新时间
eureka.server.responseCacheUpdateIntervalMs=3000
eureka.server.responseCacheAutoExpirationInSeconds=60
eureka.server.expected-client-renewal-interval-seconds=60
eureka.server.renewal-percent-threshold=0.85
eureka.server.wait-time-in-ms-when-sync-empty=10000

## 配置注册中心的主机名
eureka.instance.instance-id = eureka-2
eureka.instance.hostname = 192.168.192.15
## 服务刷新时间配置,每隔这个时间会主动心跳一次
eureka.instance.lease-renewal-interval-in-seconds= 5
## 服务提供者被认定为丢失心跳超时,失效多久后被删除
eureka.instance.lease-expiration-duration-in-seconds=15

## 配置定时获取|抓取注册中心的数据时间
eureka.client.registry-fetch-interval-seconds= 5
eureka.client.instance-info-replication-interval-seconds= 5
## 配置集群中其他eureka实例,用于本eureka实例的注册方。
eureka.client.region=beijing
eureka.client.availability-zones.beijing=zone-1,zone-3
eureka.client.service-url.zone-1=http://192.168.192.14:1111/eureka/
eureka.client.service-url.zone-3=http://192.168.192.19:1111/eureka/
  • 4.application-eureka-3.properties
server.port=1111

# 指定当前注册中心的服务名称
spring.application.name=eureka-registry

## 启用注册中心主动失效,并且每次主动失效检测间隔为5s 默认值60s
eureka.server.eviction-interval-timer-in-ms= 5000
## 设置eureka注册中心的响应更新时间
eureka.server.responseCacheUpdateIntervalMs=3000
eureka.server.responseCacheAutoExpirationInSeconds=60
eureka.server.expected-client-renewal-interval-seconds=60
eureka.server.renewal-percent-threshold=0.85
eureka.server.wait-time-in-ms-when-sync-empty=10000

## 配置注册中心的主机名
eureka.instance.instance-id = eureka-3
eureka.instance.hostname = 192.168.192.19
## 服务刷新时间配置,每隔这个时间会主动心跳一次
eureka.instance.lease-renewal-interval-in-seconds= 5
## 服务提供者被认定为丢失心跳超时,失效多久后被删除
eureka.instance.lease-expiration-duration-in-seconds=15

## 配置定时获取|抓取注册中心的数据时间
eureka.client.registry-fetch-interval-seconds= 5
eureka.client.instance-info-replication-interval-seconds= 5
## 配置集群中其他eureka实例,用于本eureka实例的注册方。
eureka.client.region=beijing
eureka.client.availability-zones.beijing=zone-1,zone-2
eureka.client.service-url.zone-1=http://192.168.192.14:1111/eureka/
eureka.client.service-url.zone-2=http://192.168.192.15:1111/eureka/
  • 5.入口类
@SpringBootApplication
@EnableEurekaServer//开启服务注解
public class EurekaServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServiceApplication.class,args);
    }
}
  • 6.打包,并上传到192.168.192.14,15,19三台服务器上
    三台机子分别运行
java -jar Eureka-Server-1.0-SNAPSHOT.jar --spring.profiles.active=eureka-1
java -jar Eureka-Server-1.0-SNAPSHOT.jar --spring.profiles.active=eureka-1
java -jar Eureka-Server-1.0-SNAPSHOT.jar --spring.profiles.active=eureka-1

启动前灵台会报错,正常的,第三台启动就OK了

启动成功
在这里插入图片描述
查看浏览器,随便运行一个ip
SpringBoot集成SpringCloud牛刀小试&Eureka单机版&Eureka集群搭建_第5张图片
SpringBoot集成SpringCloud牛刀小试&Eureka单机版&Eureka集群搭建_第6张图片

注册服务与订阅服务

只需要在application.properties中改动服务地址

eureka.client.service-url.defaultZone=http://192.168.192.14:1111/eureka/,http://192.168.192.15:1111/eureka/,http://192.168.192.19:1111/eureka/

你可能感兴趣的:(SpringBoot集成SpringCloud牛刀小试&Eureka单机版&Eureka集群搭建)