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配置
<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 这里是空的。
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页面,可以看到服务已经注册进去了
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有两个,相当于模拟一下负载均衡,看看后面消费者消费会不会分发到这两个服务里面
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,数据返回了
我们在使用rest调用一次,看看会不会分发到李四: http://127.0.0.1:8803/consumer/rest/producer?userId=2,数据返回的是李四,分发到另外一个服务者了
7、我们使用feign方式调用:http://127.0.0.1:8803/consumer/feign/producer?userId=1,也成功了
http://127.0.0.1:8803/consumer/feign/producer?userId=2,同样也分发到了另外一个服务
我使用的是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
上一篇: JVM基础知识(四)- 分代回收机制和垃圾回收算法
下一篇: 广脸达笔试复盘7.29