搭建第一个springcloud--生产者消费者和Eureka

SpringCloud是一系列框架的有序集合。它利用SpringBoot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用SpringBoot的开发风格做到一键启动和部署。SpringCloud并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过SpringBoot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
 

创建两个maven项目,一个provider,一个consumer。

两者的路径为(只展示其一consumer项目结构):

先建立两个springboot项目,一个端口为默认的8080,一个手动设置为8081(在Application.yml中设置)。

其中pom文件内容为:

<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>consumer</groupId>
  <artifactId>consumer</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>consumer</name>
  <description>consumer</description>
  <!-- 只复制下面的内容即可 -->
   <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <properties>
        <java.version>1.8</java.version>
    </properties>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
  
</project>

而springboot的入口在Application.java,用于启动项目。内容为:

package consumer;

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

@SpringBootApplication
public class Application {

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

以上为两个项目一样的内容,接下来是每个项目的不同的文件内容。

首先是providerdemo.java里面的内容:

@RestController
public class providerdemo {

	@RequestMapping("provider/demo")
	public String demo() {
		return "provider success!";
	}
}

再来是consumerdemo.java里面的内容:

@RestController
public class consumerdemo {
/*
 * 当我们从服务消费端去调用服务提供者的服务的时候,使用了一个很好用的对象,叫做RestTemplate,
 * 当时我们只使用了RestTemplate中最简单的一个功能getForEntity发起了一个get请求去调用服务端的数据
 */
	@Bean
	public RestTemplate restTemplate() {
		return new RestTemplate();
	}
	@Autowired
	private RestTemplate restTemplate;
	
	@RequestMapping("consumer/demo")
	public String consumerdemo() {
		return this.restTemplate.getForObject("http://localhost:8080/provider/demo",String.class);
		
	}
	
}

RestTemplates在SpringCloud中,消费者通过这个类访问生产者,@bean注解是为了实例化这个类,实例化之后通过@AutoWired注解引入,将其交给Spring进行管理。

扫描二维码关注公众号,回复: 6531676 查看本文章

分别启动两个类,分别访问localhost:8080/provider/demo和http://localhost:8081/consumer/demo应该都能得到provider success!这个结果,说明consumer成功调用了provider中的方法。

问题: 
这样的编码方式是将接口(http://localhost:8080/provider/demo)硬编码在代码中,但是项目发布之后,ip地址必然是变动的。而且,硬编码的方式肯定是无法实现负载均衡的,就是说如果同时启动多个provider服务,这种硬编码方式是无法根据负载均衡策略去调用服务的。

解决方法: 
在Dubbo中使用的ZooKeeper作为服务注册与发现的容器,在Springcloud中使用的是Eureka作为服务注册与发现的容器。

接下来添加一个Eureka项目,新建一个项目,pom文件为:

<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>Eureka</groupId>
  <artifactId>Eureka</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>Eureka</name>
  <description>Eureka</description>
  <!-- 只复制下面的内容即可 -->
   <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
    </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.RELEASE</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</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>

然后在Springboot的启动类上添加@EnableEurekaServer或者@EnableDiscoveryClient,这两个注解的注解的区别主要是:

@EnableEurekaServer是基于 spring-cloud-netflix依赖,只能为eureka作用,是专门给Eureka用的 
@EnableDiscoveryClient是基于 spring-cloud-commons依赖,并且在classpath中实现,是给比如zookeeper、consul使用的, 

@SpringBootApplication
@EnableEurekaServer
public class Application {

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

注意一点:SpringApplication.run(Application.class,args);里面的类名.class要与类名保持一致,是自启动。

接下来修改yml文件

server: 
  port: 8083
eureka: 
  client: 
    register-with-eureka: false
    fetch-registry: false
    service-url: 
      defaultZone: http://localhost:8082/eureka/

register-with-eureka: false这个的默认值为true,设置为true不会对使用不会有很大的影响,但是在启动的时候会保下面的错误: 
was unable to refresh its cache! status = Cannot execute request on any known server 
是因为启动的时候自己注册了自己而引起的冲突

defaultZone配置eureka的地址。

如果运行会出现以下错误问题:

java.lang.NoSuchMethodError: org.springframework.boot.builder.SpringApplicationBuilder.<init>([Ljava/lang/Object;)V

是由于spring boot版本兼容性导致的,在pom.xml中修改配置文件,修改前:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.9.RELEASE</version>
    <relativePath/>
</parent>

修改后:

<parent>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-parent</artifactId>
       <version>2.0.3.RELEASE</version>
       <relativePath/> 
</parent>

再次启动项目,成功。 (这里我只想说一句mmp,改了好几个版本,每改一次版本要等半个小时maven下载,启动起来又给我报了好多错,最后发现我随便写的端口8082竟然重复了,最后把端口改成8083就可以成功启动了)

启动成功输入 http://localhost:8083/(根据自己的端口)就可以看见eureka界面。

接着我们要把provider和consumer都放在注册中心中,那么我们需要更改一些pom文件

两者pom文件相同,只列其一:

<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>springcloud</groupId>
  <artifactId>springcloud</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>springcloud</name>
  <description>springcloud</description>
  
<!-- 只复制下面的内容即可 -->
   <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.3.RELEASE</version>
    </parent>


    <dependencies>
    <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-web</artifactId>
        </dependency>
    </dependencies>
  <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <properties>
        <java.version>1.8</java.version>
    </properties>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
  
</project>

更改了parent的版本号,增加了这个spring-cloud-starter-netflix-eureka-client。

在这里强调一下dependencyManagement和dependency的关系

1.在Maven中dependencyManagement的作用其实相当于一个对所依赖jar包进行版本管理的管理器。

2.pom.xml文件中,jar的版本判断的两种途径

(1):如果dependencies里的dependency自己没有声明version元素,那么maven就

会倒dependencyManagement里面去找有没有对该artifactId和groupId进行过版本声明,如果有,就继承它,如果

没有就会报错,告诉你必须为dependency声明一个version

(2):如果dependencies中的dependency声明了version,那么无论dependencyManagement中有无对该jar的version声明,都以dependency里的version为准。

问题:如果版本不一致会出现的这样的错误。

JavaWeb:java.lang.NoClassDefFoundError: org/springframework/core/OrderComparator$OrderSourceProvider

要保持springboot和springcloud的版本一致。

回到正题,继续走,接着更改provider和consumer的启动项,在项目的启动类上添加@EnableEurekaClient注解

更改provider和consumer的yml文件

server: 
  port: 8080
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8083/eureka/
spring:
  application:
    name: provider-demo

在yml文件中添加上eureka注册中心的地址defaultZone: http://localhost:8083/eureka/

如果自己不给它设置name,application的名称为UNKNOWN。

consumer的yml文件同理。

最后先启动eureka,再启动provider、consumer,在注册中心就可以看见:

这样,第一个springcloud就搭建完了,一个经典的生产者消费者加上eureka的注册中心,这部分有什么疑问可以留言,我也是刚开始学习,能帮忙就尽量帮忙。

猜你喜欢

转载自blog.csdn.net/qq_39404258/article/details/89552548