Spring Cloud --Eureka

微服务中间件
1.服务治理和服务发现(Spring Cloud Netflix Eureka)
2.服务调用(Spring Cloud Netflix Ribbon and Spring Cloud Netflix OpenFeign)
3.断路器(Spring Cloud Netflix Hystrix and Resilience4j)
4.网关(Spring Cloud Netflix Zuul and Spring Cloud Gateway)
5.服务配置(Spring Cloud Config)
6.服务监控(Spring Cloud Sleuth and Spring Boot Admin)

第一节 Eureka
1.搭建服务治理中心集群
pom.xml

<?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.1.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>spring.cloud</groupId>
    <artifactId>eureka-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>eureka-server</name>
    <description>eureka-server project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
    </properties>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</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>

application.yml

spring:
  application:
    name:  eureka-server  # 定义Spring应用名称,它是一个微服务注册到服务器时的名称,一个微服务可拥有多个实例
  profiles:
    active: peer1  # 当配置为“peer2”时选择application-peer2.yml作为配置文件
eureka:
  client:
    eureka-server-connect-timeout-seconds: 20  #连接Eureka Server的超时时间,单位:秒
    enabled: true  #用于指示Eureka客户端已启用的标志
    fetch-registry: true  #客户端是否获取eureka服务器注册表上的注册信息,默认为true
    register-with-eureka: true  #指示此实例是否应将其信息注册到eureka服务器以供其他服务发现,默认为false
  server:
    enable-self-preservation: false  #启用自我保护机制,默认为truefalse时控制台提示(THE SELF PRESERVATION
    renewal-percent-threshold: 0.85 # eureka的阈值(默认值)是0.85(当注册在eureka中的正常服务占比低于85%时会开启eureka的自我保护)
									#也就是说Eureka Server在运行期间会去统计心跳失败比例在 15 分钟之内是否低于 85%,
									#如果低于 85%Eureka Server 会将这些实例保护起来,让这些实例不会过期
									#每分钟需要收到的续约次数阈值(心跳数/client实例数)
    eviction-interval-timer-in-ms: 30000   #清除无效服务实例的时间间隔(ms),默认1分钟
    use-read-only-response-cache: false  #是否从readonly(只读缓存)中读取实例(默认是true)
    peer-node-read-timeout-ms: 60000  #读超时时间

application-peer1.yml

server:
  port: 5001 #修改内嵌Tomcat端口为5001
eureka:
  client:
    service-url:
      defaultZone: http://localhost:5002/eureka/,http://localhost:5003/eureka/  # 服务注册地址
  instance:
    hostname: localhost1 #实例名称
    prefer-ip-address: false   #为true时使用ip而不是主机名,这里必须使用主机名

application-peer2.yml

server:
  port: 5002 #修改内嵌Tomcat端口为5001
eureka:
  client:
    service-url:
      defaultZone: http://localhost:5001/eureka/,http://localhost:5003/eureka/  # 服务注册地址
  instance:
    hostname: localhost2 #实例名称
    prefer-ip-address: false   #为true时使用ip而不是主机名,这里必须使用主机名

application-peer3.yml

server:
  port: 5003 #修改内嵌Tomcat端口为5001
eureka:
  client:
    service-url:
      defaultZone: http://localhost:5002/eureka/,http://localhost:5001/eureka/  # 服务注册地址
  instance:
    hostname: localhost3 #实例名称
    prefer-ip-address: false   #为true时使用ip而不是主机名,这里必须使用主机名

启动类 EurekaServerApplication.java

package com.spring.cloud.eureka.server.main;

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

/**** imports ****/
@SpringBootApplication
// 驱动Eureka服务治理中心
@EnableEurekaServer
public class EurekaServerApplication {

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

第二节搭建业务微服务实例

产品,资金,俩个微服务
公共bean
ResultMessage.java

package com.spring.cloud.common.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ResultMessage {
    private boolean success;
    private String message;
}

资金微服务
pom.xml

<?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.1.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>spring.cloud</groupId>
    <artifactId>fund</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>fund</name>
    <description>fund project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>io.github.resilience4j</groupId>
            <artifactId>resilience4j-spring-boot2</artifactId>
            <version>0.13.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-okhttp</artifactId>
        </dependency>
        <!-- 依赖feign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- 依赖hystrix -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </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>
		<!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </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>

启动类

package com.spring.cloud.fund.main;

import okhttp3.OkHttpClient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;

import java.util.concurrent.TimeUnit;

/**** imports ****/
@SpringBootApplication( // 扫描装配Bean
        scanBasePackages = "com.spring.cloud.fund")
@EnableFeignClients( // 扫描装配OpenFeign接口到IoC容器中
        basePackages="com.spring.cloud.fund")
public class FundApplication {
    public static void main(String[] args) {
        SpringApplication.run(FundApplication.class, args);
    }

    @Bean
    public OkHttpClient.Builder okHttpClientBuilder() {
        return new OkHttpClient.Builder()
                // 读取超时时间(不包含解析地址,提交请求的耗时)
                .readTimeout(2, TimeUnit.SECONDS)
                // 写入超时时间
                .writeTimeout(5, TimeUnit.SECONDS)
                // 连接远程服务器超时时间
                .connectTimeout(3, TimeUnit.SECONDS)
                // 如果连接远程服务器失败是否重试
                .retryOnConnectionFailure(true)
                // 当HTTP返回码为3xx(重定向)时,是否执行重定向操作
                .followRedirects(true);
    }
}

控制器

package com.spring.cloud.fund.controller;

import javax.servlet.http.HttpServletRequest;

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.spring.cloud.common.vo.ResultMessage;

/**** imports ****/
@RestController
@RequestMapping("/fund")
public class AccountController {
    // 扣减账户资金
    @PostMapping("/account/balance/{userId}/{amount}")
    public ResultMessage deductingBalance(
            @PathVariable("userId") Long userId,
            @PathVariable("amount") Double amount,
            HttpServletRequest request) {
        // 打印当前服务的端口用于监测
        String message = "端口:【" + request.getServerPort() + "】扣减成功";
        ResultMessage result = new ResultMessage(true, message);
        return result;
    }
}

产品微服务
pom.xml

<?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.1.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>spring.cloud</groupId>
    <artifactId>product</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>product</name>
    <description>product project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </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>
        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </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>

启动类

package com.spring.cloud.product.main;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
import java.time.Duration;

@SpringBootApplication(scanBasePackages = "com.spring.cloud.product")
@EnableCircuitBreaker
public class ProductApplication {
    // 负载均衡
    @LoadBalanced
	// 创建Spring Bean
    @Bean
    public RestTemplate initRestTemplate() {
        return new RestTemplate();
    }
}

ProductController.java

package com.spring.cloud.product.controller;

import com.spring.cloud.common.vo.ResultMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

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

@RestController
@RequestMapping("/product")
public class ProductController {
    // 依赖注入RestTempalte
    @Autowired
    private RestTemplate restTemplate = null;

    @GetMapping("/purchase/{userId}/{productId}/{amount}")
    public ResultMessage purchaseProduct(
            @PathVariable("userId")  Long userId,
            @PathVariable("productId") Long productId,
            @PathVariable("amount") Double amount) {
        System.out.println("扣减产品余额。");
        // 这里的FUND代表资金微服务,RestTemplate会自动负载均衡
        String url = "http://FUND/fund/account/balance/{userId}/{amount}";
        // 封装请求参数
        Map<String, Object> params = new HashMap<>();
        params.put("userId", userId);
        params.put("amount", amount);
        // 请求资金微服务
        ResultMessage rm = restTemplate.postForObject(url, null, ResultMessage.class, params );
        // 打印资金微服务返回的消息
        System.out.println(rm.getMessage());
        System.out.println("记录交易信息");
        return new ResultMessage(true,"交易成功");
    }
}

然后启动三个注册中心、
java -jar eureka-server-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer1
java -jar eureka-server-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer2
java -jar eureka-server-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer3

接着启动两个资金实例
java -jar fund-0.0.1-SNAPSHOT.war --spring.profiles.active=peer1
java -jar fund-0.0.1-SNAPSHOT.war --spring.profiles.active=peer2

再启动两个产品实例
java -jar product-0.0.1-SNAPSHOT.war --spring.profiles.active=peer1
java -jar product-0.0.1-SNAPSHOT.war --spring.profiles.active=peer2

访问网址http://localhost:8001/product/purchase/1/1/1000

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

芊芸爸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值