SpringCloud入门hello world,SpringBoot2.1.3,附采坑经历(附源码)

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配置


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


        1.8
        Greenwich.SR2


        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-server
        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-client
        
    

    
        
            
                org.springframework.cloud
                spring-cloud-dependencies
                ${spring-cloud.version}
                pom
                import
            
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    

    
        
            spring-milestones
            Spring Milestones
            https://repo.spring.io/milestone
        

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,附采坑经历(附源码)_第1张图片

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,附采坑经历(附源码)_第2张图片

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,附采坑经历(附源码)_第3张图片

4、创建Eureka 消费者

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


        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-client
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-ribbon
        
        
            org.springframework.cloud
            spring-cloud-starter-openfeign
        
    

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,附采坑经历(附源码)_第4张图片
我们在使用rest调用一次,看看会不会分发到李四: http://127.0.0.1:8803/consumer/rest/producer?userId=2,数据返回的是李四,分发到另外一个服务者了
SpringCloud入门hello world,SpringBoot2.1.3,附采坑经历(附源码)_第5张图片
7、我们使用feign方式调用:http://127.0.0.1:8803/consumer/feign/producer?userId=1,也成功了
SpringCloud入门hello world,SpringBoot2.1.3,附采坑经历(附源码)_第6张图片
http://127.0.0.1:8803/consumer/feign/producer?userId=2,同样也分发到了另外一个服务
SpringCloud入门hello world,SpringBoot2.1.3,附采坑经历(附源码)_第7张图片

我使用的是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://github.com/wangyi0102/SpringCloudDemo

你可能感兴趣的:(java)