文章目录
  1. 1. 7天学会使用springcloud(一)
    1. 1.1. 什么是spring cloud?
    2. 1.2. 快速入门
    3. 1.3. 什么是eureka
    4. 1.4. eureka 干嘛用的
    5. 1.5. 如何使用
    6. 1.6. 建立app-client

7天学会使用springcloud(一)

什么是spring cloud?

官方解释:

Spring Cloud

Spring Cloud provides tools for developers to quickly build some of the common patterns in distributed systems (e.g. configuration management, service discovery, circuit breakers, intelligent routing, micro-proxy, control bus, one-time tokens, global locks, leadership election, distributed sessions, cluster state). Coordination of distributed systems leads to boiler plate patterns, and using Spring Cloud developers can quickly stand up services and applications that implement those patterns. They will work well in any distributed environment, including the developer’s own laptop, bare metal data centres, and managed platforms such as Cloud Foundry.

意思是spring Cloud 是为快速开发生产系统提供的一系列公用组件或者工具。实现快速启动应用服务,让开发到生产更简单。

嗯,官方点进去还有一段:

Spring Cloud builds on Spring Boot by providing a bunch of libraries that enhance the behaviour of an application when added to the classpath. You can take advantage of the basic default behaviour to get started really quickly, and then when you need to, you can configure or extend to create a custom solution.

spring cloud是作为组件库的形式运行在spring boot上的。你可以下载官方基础版本来快速在其基础上开发或者你额外创建一个自定义项目。

快速入门

  1. 从官方网站下载带有springcloud基本组件的eureka Server(等下再介绍它的作用)

1523008669657fh46tqfu

  1. 直接用idea新建springboot项目,添加上eureka Server组件

paste image

152300877569093stlsyw

1523008812084dn7tifyo

以下睁大眼看看,eureka server组件是cloud config里的

1523008886524lwpx5d9m

什么是eureka

先来介绍一下netflix

Spring Cloud Netflix
Spring Cloud Netflix provides Netflix OSS integrations for Spring Boot apps through autoconfiguration and binding to the Spring Environment and other Spring programming model idioms. With a few simple annotations you can quickly enable and configure the common patterns inside your application and build large distributed systems with battle-tested Netflix components. The patterns provided include Service Discovery (Eureka), Circuit Breaker (Hystrix), Intelligent Routing (Zuul) and Client Side Load Balancing (Ribbon)..

netflix 通过用一些简单的注解快速启动和配置组件自动配置和绑定环境变量为spring boot 应用提供OSS 集成。

eureka它是Spring Cloud Netflix的Eureka ,eureka是一个服务注册和发现模块。

官网的介绍:

Eureka is a REST (Representational State Transfer) based service that is primarily used in the AWS cloud for locating services for the purpose of load balancing and failover of middle-tier servers. We call this service, the Eureka Server. Eureka also comes with a Java-based client component,the Eureka Client, which makes interactions with the service much easier. The client also has a built-in load balancer that does basic round-robin load balancing. At Netflix, a much more sophisticated load balancer wraps Eureka to provide weighted load balancing based on several factors like traffic, resource usage, error conditions etc to provide superior resiliency.

eureka是一种 REST (代表状态转移) 的服务, 主要用于 AWS(即自动报警系统) 云中, 用于定位服务, 以便于中间层服务器的负载均衡和故障切换。我们称之为服务, eureka服务器。eureka还附带了一个基于 Java 的客户端组件, eureka client, 这使得与服务的交互变得容易得多。客户端还具有内置的负载均衡器, 可进行基本的循环负载均衡。在 Netflix, 一个更复杂的负载均衡器包装eureka提供权重负载均衡的基础上的几个因素, 如流量, 资源使用, 错误条件等, 以提供优越的弹性。

eureka 干嘛用的

官方:

In AWS cloud, because of its inherent nature, servers come and go. Unlike the traditional load balancers which work with servers with well known IP addresses and host names, in AWS, load balancing requires much more sophistication in registering and de-registering servers with load balancer on the fly. Since AWS does not yet provide a middle tier load balancer, Eureka fills a big gap in the area of mid-tier load balancing.

由于AWS云它固有的特性, 服务器来了又走。
与使用已知 IP 地址和主机名的服务器的传统负载均衡器不同, 在 AWS 中, 负载均衡在使用负载平衡器进行注册和取消注册服务器时更加复杂。由于 AWS 还没有提供中间层负载平衡器, eureka填补了中端(应用层)负载平衡领域的巨大缺口。

也就是说用eureka可以实现负载均衡快速切换,而且可以不需要知道ip地址。

如何使用

eureka分client和server端

image-20220117144224715

client端又分为service和client

从图可以看出在这个体系中,有2个角色,即Eureka Server和Eureka Client。而Eureka Client又分为Applicaton Service和Application Client,即服务提供者和服务消费者。 每个区域有一个Eureka集群,并且每个区域至少有一个eureka服务器可以处理区域故障,以防服务器瘫痪。

Eureka Client向Eureka Server注册,并将自己的一些客户端信息发送Eureka Server。然后,Eureka Client通过向Eureka Server发送心跳(每30秒)来续约服务的。 如果客户端持续不能续约,那么,它将在大约90秒内从服务器注册表中删除。 注册信息和续订被复制到集群中的Eureka Server所有节点。 来自任何区域的Eureka Client都可以查找注册表信息(每30秒发生一次)。根据这些注册表信息,Application Client可以远程调用Applicaton Service来消费服务。

springboot集成eureka.

在springboot的application启动里上添加一个启动eureka注解:

1523073798777qh7i8cb1

如果是从官网下载的springboot初始项目运行,可能会报错:

  java.lang.IllegalStateException: Error processing condition on org.springframework.cloud.netflix.eureka.server.EurekaServerAutoConfiguration.peerEurekaNodes
  at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:64) ~[spring-boot-autoconfigure-2.0.0.RELEASE.jar:2.0.0.RELEASE]
  at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:109) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
  at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:179) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
  at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:141) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
  at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:117) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
  at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:328) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
  at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:233) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
  at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:273) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
  at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:93) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
  at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:693) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
  at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:531) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
  at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
  at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:388) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
  at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
  at org.springframework.boot.SpringApplication.run(SpringApplication.java:1246) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
  at org.springframework.boot.SpringApplication.run(SpringApplication.java:1234) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
  at com.example.cloud.EurekaServerApplication.main(EurekaServerApplication.java:12) [classes/:na]
  Caused by: java.lang.IllegalStateException: Failed to introspect Class [org.springframework.cloud.netflix.eureka.server.EurekaServerAutoConfiguration] from ClassLoader [sun.misc.Launcher$AppClassLoader@18b4aac2]
  at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:659) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
  at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:556) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
  at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:541) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
  at org.springframework.util.ReflectionUtils.getUniqueDeclaredMethods(ReflectionUtils.java:599) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:728) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:669) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:637) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
  at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1489) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
  at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1007) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
  at org.springframework.boot.autoconfigure.condition.BeanTypeRegistry.addBeanTypeForNonAliasDefinition(BeanTypeRegistry.java:168) ~[spring-boot-autoconfigure-2.0.0.RELEASE.jar:2.0.0.RELEASE]
  at org.springframework.boot.autoconfigure.condition.BeanTypeRegistry.addBeanType(BeanTypeRegistry.java:157) ~[spring-boot-autoconfigure-2.0.0.RELEASE.jar:2.0.0.RELEASE]
  at org.springframework.boot.autoconfigure.condition.BeanTypeRegistry.updateTypesIfNecessary(BeanTypeRegistry.java:207) ~[spring-boot-autoconfigure-2.0.0.RELEASE.jar:2.0.0.RELEASE]
  at org.springframework.boot.autoconfigure.condition.BeanTypeRegistry.getNamesForType(BeanTypeRegistry.java:114) ~[spring-boot-autoconfigure-2.0.0.RELEASE.jar:2.0.0.RELEASE]
  at org.springframework.boot.autoconfigure.condition.OnBeanCondition.collectBeanNamesForType(OnBeanCondition.java:266) ~[spring-boot-autoconfigure-2.0.0.RELEASE.jar:2.0.0.RELEASE]
  at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getBeanNamesForType(OnBeanCondition.java:255) ~[spring-boot-autoconfigure-2.0.0.RELEASE.jar:2.0.0.RELEASE]
  at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchingBeans(OnBeanCondition.java:197) ~[spring-boot-autoconfigure-2.0.0.RELEASE.jar:2.0.0.RELEASE]
  at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchOutcome(OnBeanCondition.java:116) ~[spring-boot-autoconfigure-2.0.0.RELEASE.jar:2.0.0.RELEASE]
  at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47) ~[spring-boot-autoconfigure-2.0.0.RELEASE.jar:2.0.0.RELEASE]
  ... 16 common frames omitted
  Caused by: java.lang.NoClassDefFoundError: javax/ws/rs/core/Application
  at java.lang.Class.getDeclaredMethods0(Native Method) ~[na:1.8.0_74]
  at java.lang.Class.privateGetDeclaredMethods(Class.java:2701) ~[na:1.8.0_74]
  at java.lang.Class.getDeclaredMethods(Class.java:1975) ~[na:1.8.0_74]
  at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:641) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
  ... 33 common frames omitted
  Caused by: java.lang.ClassNotFoundException: javax.ws.rs.core.Application
  at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_74]
  at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_74]
  at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) ~[na:1.8.0_74]
  at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_74]
  ... 37 common frames omitted

我们找到报错原因:

 Caused by: java.lang.NoClassDefFoundError: javax/ws/rs/core/Application

就是说Application类没找到,这是javax的ws.rs包默认是没有的,一般如果我们直接通过application启动,则会报这个错,但是如果用tomcat容器呢?这个还没试,后面有时间试下。

我把这个包加到pom.xml:

    <dependency>
    <groupId>javax.ws.rs</groupId>
    <artifactId>javax.ws.rs-api</artifactId>
    <version>2.0.1</version>
    <scope>jar</scope>
    </dependency>

再运行,成功。

访问:http://localhost:8888

1523075571296i1lje386

看看我的配置文件:

application.yml:

server:
  port: 8888


logging:
  level:
    com.netflix.discovery: 'OFF'
    org.springframework.cloud: 'DEBUG'

eureka:
  instance:
    leaseRenewalIntervalInSeconds: 10
    statusPageUrlPath: /admin/info
    healthCheckUrlPath: /admin/health

eureka:
  instance:
    hostname: localhost
    nonSecurePort: 80
  client:
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
    registerWithEureka: false
    fetchRegistry: false

registerWithEureka: 值为false意味着自身仅作为服务器,不作为客户端

fetchRegistry: 值为false意味着无需注册自身

serviceUrl.defaultZone: 指明了应用的URL

关于配置,参考官方文档

建立app-client

client其实是调用服务提供者来消费的一个client,我们来建立一个app-client

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>eureka-client1</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>eureka-client1</name>
    <description>Demo project for Spring Boot(spring cloud)</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.M9</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.cloud</groupId>
            <artifactId>spring-cloud-starter-config</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>
        </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>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>


</project>

入口类EurekaClientApplication:

package com.example.cloud;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@SpringBootApplication
public class EurekaClientApplication {

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


    @Value("${server.port}")
    String port;
    @RequestMapping("/hi")
    public String home(@RequestParam String name) {
            return
                "hi "+name+",i am from port:" +port;
    }

}

配置文件:

spring:
  application:
    name: client-service
  cloud:
    config:
      uri: http://localhost:8761/
      label: master
      profile: dev
  security:
    user:
      name: sam
      password: 123456


eureka:
  instance:
    hostname: localhost
    prefer-ip-address: true
    instance-id: ${eureka.instance.hostname}:${server.port}
    nonSecurePort: 80
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka


logging:
  level:
    org:
      springframework:
        security: DEBUG
server:
  port: 8882

spring.cloud.vault:
    config.lifecycle.enabled: true
    fail-fast: true

写一个restController测试接口,启动后刷新eurake页面,发现已经注册进去了:

1525008085202ufhuf38m

那我们访问那个接口试下client是否正常运行:

http://localhost:8882/hi?name=test

发现访问正常。

文章目录
  1. 1. 7天学会使用springcloud(一)
    1. 1.1. 什么是spring cloud?
    2. 1.2. 快速入门
    3. 1.3. 什么是eureka
    4. 1.4. eureka 干嘛用的
    5. 1.5. 如何使用
    6. 1.6. 建立app-client