欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SpringCloud入门hello world,SpringBoot2.1.3,附采坑经历

程序员文章站 2022-05-18 17:48:58
SpringCloud入门Hello worldSpringCloud是Spring开源的一个基于SpringBoot的分布式微服务框架。它提供了微服务开发所需的配置管理、服务发现、断路器、智能路由、微代理、控制总线、全局锁、决策竞选、分布式会话和集群状态管理等组件。而且是基于SpringBoot的,所以整合起来很方便!先解释一下SpringCloud的核心组件:SpringCloud五大核心组件1、Eureka:Eureka是Netflix开源的一个RESTful服务,也称服务注册中心。主要用于...

SpringCloud入门Hello world

SpringCloud是Spring开源的一个基于SpringBoot的分布式微服务框架。它提供了微服务开发所需的配置管理、服务发现、断路器、智能路由、微代理、控制总线、全局锁、决策竞选、分布式会话和集群状态管理等组件。而且是基于SpringBoot的,所以整合起来很方便!
先解释一下SpringCloud的核心组件:

SpringCloud五大核心组件

1、Eureka:
Eureka是Netflix开源的一个RESTful服务,也称服务注册中心。主要用于服务的注册发现。Eureka由两个组件组成:Eureka服务器和Eureka客户端。
Eureka Server用作服务注册中心,里面有一个注册表,保存了各个服务所在的机器和端口号。支持高可用配置,可以配置自动剔除有故障的服务(心跳),当故障服务恢复时会自动同步回来继续提供服务。
Eureka Client客户端这个组件专门负责将这个服务的信息注册到Eureka Server中。其实就是告诉Eureka Server,我在哪台机器上,监听着哪个端口。而Eureka Server注册中心里面有一个注册表,保存了各服务所在的机器和端口号。

2、Ribbon:
Ribbon是一个基于HTTP和TCP的客户端负载均衡器,它可以在通过客户端中配置的ribbonServerList服务端列表去轮询访问以达到服务均衡的作用,它的作用是负载均衡,会帮你在每次请求时选择一台机器,均匀的把请求分发到各个机器上。

3、Feign:
Fegin最关键的机制是使用了动态代理,为我们要请求的服务创建代理。Fegin核心注解@FeignClient。使用Fegin时,对某个接口加上@FeignClient注解,Feign就会针对这个接口创建一个动态代理,然后调用这个接口,本质就是会调用 Feign创建的动态代理,Feign的动态代理会根据你在接口上的@FeignClient @RequestMapping等注解,来动态构造出你要请求的服务和具体的地址,最后针对这个地址,发起请求、解析响应,所有的东西都封装好了。

4、Hystrix:
Hystrix是隔离、熔断以及降级的一个框架。Hystrix具备服务降级、服务熔断、线程和信号隔离、请求缓存、请求合并以及服务监控等强大功能

5、Zuul:
Zuul是微服务网关。这个组件是负责网络路由的,提供智能路由、访问过滤等功能。

SpringCloud Hello world

下面就是SpringCloud入门HelloWorld,还有一些自己在研究的时候遇到的一些问题

1、创建Eureka Server注册中心

1、新建一个SpringBoot项目,我命名为SpringCloudDemo,这里要注意了,有一个坑,SpringBoot版本不同,对应的SpringCloud版本也不一样,有一些连名称都修改了,这里要注意自己的SpringBoot版本是多少,我使用的SpringBoot版本是2.1.3,SpringCloud版本是Greenwich.SR2,我刚开始是Greenwich.SR1版本,在使用Feign的时候一个报错,找不到原因,后面换成Greenwich.SR2 就可以了 ==~,版本问题可以参考 :SpringBoot对应SpringCloud版本
添加maven依赖,这些依赖放在父类里面,后面的模块就不重复导入了。在SpringCloudDemo里面新建项目 server,parent就是SpringCloudDemo,自动继承里面的maven配置

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
        <relativePath/> 
</parent>
<properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR2</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.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</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>

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

2、server模块的application.properties配置

#注册中心服务ID
spring.application.name=server
#端口号
server.port=8800
# eureka.client.registerWithEureka :表示是否将自己注册到Eureka Server,默认为true。
# 由于当前这个应用就是Eureka Server,设为false
eureka.client.register-with-eureka=false
# eureka.client.fetchRegistry :表示是否从Eureka Server获取注册信息,默认为true。因为这是一个单点的Eureka Server,
# 不需要同步其他的Eureka Server节点的数据,设为false。
eureka.client.fetch-registry=false
# eureka.client.serviceUrl.defaultZone :设置与Eureka Server交互的地址,查询服务和注册服务都需要依赖这个地址
eureka.client.serviceUrl.defaultZone=http://localhost:8800/eureka/
# 关闭保护机制,默认true
eureka.server.enable-self-preservation=false
# 剔除失效服务间隔,默认60000
eureka.server.eviction-interval-timer-in-ms=2000

3、运行启动server项目,@EnableEurekaServer表示是服务端

@EnableEurekaServer
@SpringBootApplication
public class ServerApplication {
    public static void main(String args[]){
        SpringApplication.run(ServerApplication.class, args);
    }
}

4、打开Eureka服务端页面:http://localhost:8800 ,可以看到以下页面,目前没有服务注册,所以 Instances currently registered with Eureka 这里是空的。
SpringCloud入门hello world,SpringBoot2.1.3,附采坑经历

2、创建Eureka Client服务提供者1

1、新建项目producer
2、application.properties配置

#注册中心服务ID
spring.application.name=producer
#端口号
server.port=8801
#在注册中心中进行注册
eureka.client.serviceUrl.defaultZone=http://localhost:8800/eureka/
#启动服务发现的功能,开启了才能调用其它服务
spring.cloud.config.discovery.enabled=true
#发现的服务的名字--对应注测中心的服务名字
spring.cloud.config.discovery.serviceId=server
#Eureka客户端向服务端发送心跳的时间间隔,单位为秒,默认30
eureka.instance.lease-renewal-interval-in-seconds=1
#Eureka服务端在收到最后一次心跳之后等待的时间上限,单位为秒,超过则剔除,默认90
eureka.instance.lease-expiration-duration-in-seconds=2

3、提供一个接口

@RestController
public class UserController {
    @GetMapping("/user/info")
    public String getUserInfo(Long userId){
        return "this is 张三,男,18岁,userId is" + userId;
    }
}

4、启动服务1,@EnableEurekaClient 表示自己是客户端

@EnableEurekaClient
@SpringBootApplication
public class ProducerApplication {
    public static void main(String args[]){
        SpringApplication.run(ProducerApplication.class, args);
    }
}

5、刷新eureka页面,可以看到服务已经注册进去了
SpringCloud入门hello world,SpringBoot2.1.3,附采坑经历

3、创建Eureka Client服务提供者2

1、新建项目producerTwo
2、application.properties配置

#注册中心服务ID,和producer一样,相当于模拟负载均衡
spring.application.name=producer
#端口号修改为8802
server.port=8802
#在注册中心中进行注册
eureka.client.serviceUrl.defaultZone=http://localhost:8800/eureka/
#启动服务发现的功能,开启了才能调用其它服务
spring.cloud.config.discovery.enabled=true
#发现的服务的名字--对应注测中心的服务名字
spring.cloud.config.discovery.serviceId=server
#Eureka客户端向服务端发送心跳的时间间隔,单位为秒,默认30
eureka.instance.lease-renewal-interval-in-seconds=1
#Eureka服务端在收到最后一次心跳之后等待的时间上限,单位为秒,超过则剔除,默认90
eureka.instance.lease-expiration-duration-in-seconds=2

3、提供一个接口

@RestController
public class UserController {
    @GetMapping("/user/info")
    public String getUserInfo(Long userId){
        return "this is 李四,女,20岁,userId is" + userId;
    }
}

4、启动服务2,@EnableEurekaClient 表示自己是客户端

@EnableEurekaClient
@SpringBootApplication
public class ProducerTwoApplication {
    public static void main(String args[]){
        SpringApplication.run(ProducerTwoApplication .class, args);
    }
}

5、刷新eureka页面,可以看到服务2已经注册进去了,这里只有一条记录,叫producer,但是后面Status有两个,相当于模拟一下负载均衡,看看后面消费者消费会不会分发到这两个服务里面
SpringCloud入门hello world,SpringBoot2.1.3,附采坑经历

4、创建Eureka 消费者

1、新建项目consumer,添加maven依赖,这里也要注意一下spring-cloud-starter-openfeign的名称,SpringCloud版本不同,这个名称也不一样,这个是使用feign要用到的jar包

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

2、application.properties配置

#注册中心服务ID
spring.application.name=consumer
#端口号
server.port=8803
#在注册中心中进行注册
eureka.client.serviceUrl.defaultZone=http://localhost:8800/eureka/

3、创建ProducerService接口,提供feign调用方式,@FeignClient(“producer”),这里的producer就是服务提供者的名称,@GetMapping("/user/info"),这个接口就是服务提供者的接口,要一样才可以,@RequestParam(“userId”)接口里面的参数要加上注解,明确这个参数的名称,我刚开始没有加,就报错了提示:feign.FeignException$MethodNotAllowed: status 405 reading ProducerService

@FeignClient("producer")
public interface ProducerService {

    @GetMapping("/user/info")
    String getUserInfo(@RequestParam("userId") Long userId);
}

4、RestTemplate加入Bean容器中,@EnableFeignClients 表示开启Feign服务,这样@FeignClient才生效

@SpringBootApplication
@EnableFeignClients
@EnableEurekaClient
@EnableDiscoveryClient
public class ConsumerApplication {

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

    @LoadBalanced //使用负载均衡机制
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

5、创建接口调用服务,这里有两种调用方式,一种是Rest调用,一种是feign调用,上面已经配置好了,这里直接注入Bean调用

@RestController
@RequestMapping("/consumer")
public class ConsumerController {

    @Resource
    private RestTemplate restTemplate;
    @Resource
    private ProducerService producerService;

    // Rest远程调用
    @GetMapping("/rest/producer")
    public String restPro(Long userId){
        return restTemplate.getForObject("http://producer/user/info?userId="+userId, String.class);
    }

    // feign调用
    @GetMapping("/feign/producer")
    public String feignPro(Long userId){
        return producerService.getUserInfo(userId);
    }

}

6、启动项目,rest调用1: http://127.0.0.1:8803/consumer/rest/producer?userId=1,数据返回了
SpringCloud入门hello world,SpringBoot2.1.3,附采坑经历
我们在使用rest调用一次,看看会不会分发到李四: http://127.0.0.1:8803/consumer/rest/producer?userId=2,数据返回的是李四,分发到另外一个服务者了
SpringCloud入门hello world,SpringBoot2.1.3,附采坑经历
7、我们使用feign方式调用:http://127.0.0.1:8803/consumer/feign/producer?userId=1,也成功了
SpringCloud入门hello world,SpringBoot2.1.3,附采坑经历
http://127.0.0.1:8803/consumer/feign/producer?userId=2,同样也分发到了另外一个服务
SpringCloud入门hello world,SpringBoot2.1.3,附采坑经历

我使用的是SpringBoot2.1.3,SpringCloud是Greenwich.SR2,我刚开始使用的是Greenwich.SR1,访问一直报错提示:NoSuchMethodError: feign.Request.requestTemplate(),后面才发现是版本的问题。
还遇到一个问题:
feign.FeignException$MethodNotAllowed: status 405 reading ProducerService,这个是使用feign调用的时候,服务提供者接口里面的参数名称是userId,消费者消费的时候没有在参数上指定@RequestParam(“userId”) Long userId,所以报错了。
感觉SpringCloud使用还是比较方便的,支持的功能也很强大。

本文地址:https://blog.csdn.net/wang_o_yi/article/details/107654584

相关标签: java