最近这段时间接口写完了,就配合前端同事对接口,所以空闲的时间还是有的,就学习了起来,由于之前用的都是springboot,没有用到springcloud,所以就自己学着玩了起来,这篇博客仅仅是记录自己学习过程,方便以后回顾一下,勿喷勿喷。。。之前也写过构建的博客,发现以前写的有个小问题没跑起来,自己又不想修改之前的博客,所以特地重新写一个详细点的。
咋们开门见山,理论知识这边博客就不讨论了,直接看怎么构建项目嗨起来
构建一个eureka服务的注册中心,eureka提供服务的注册和发现功能
构建一个maven项目:
随便起个名字:
项目路径,自己定义哦!定义好之后点击finish
新创建的项目结构为:
打开最左上角的File,点击setting
设置maven本地仓库配置:
新建一个module,是一个个的springboot项目
随便起一个名字:
接下来就是选择相应的依赖了:
接下来我们看到的项目构造是:
下面我们要做的就是配置eureka的相关信息了:在resources下面有application.properties文件中配置,如果大家觉得不习惯可以用yml文件也是一样的,看个人习惯吧,我这里暂时就用application.properties
server.port=1111
eureka.instance.hostname=localhost
#由于该应用为注册中心,所以设置为false 代表不向注册中心注册自己
eureka.client.register-with-eureka=false
#由于注册中心的职责就是维护服务实例,它并不需要去检索服务,所以为false
eureka.client.fetch-registry=true
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
配置文件配置好了以后,我们去项目的启动类中加上@EnableEurekaServer:
@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
运行项目后,我们访问:http://localhost:1111
可以看到:
此时项目中没有任何的服务,接下来我们开始写服务提供者:
再在右击项目名字,module,创建一个springboot项目,然后给项目命名字
依然是选上相应的依赖,注意和上面的依赖有什么不一样:
有时候这个目录不对,项目结构也就不对了,大家还是注意一下,有时候手动改动一下项目这个目录哦
我在这把producer01的pom文件代码复制出来:
<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-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
接下来我们还是去写配置文件:
server.port=8081
#为服务命名
spring.application.name=hello-service
#指定服务注册中心的地址
eureka.client.service-url.defaultZone=http://localhost:1111/eureka/
#服务续约 定义服务续约任务的调用间隔时间,默认30秒
eureka.instance.lease-renewal-interval-in-seconds=30
#服务续约 定义服务失效的时间
eureka.instance.lease-expiration-duration-in-seconds=90
新建一个controller包
新建一个类
@RestController
public class ProController {
@RequestMapping(value = "/hello",method = RequestMethod.GET)
public String pro(){
return "this is one";
}
}
同样的在启动类上面加上一个注解:@EnableDiscoveryClient
@EnableDiscoveryClient
@SpringBootApplication
public class Producer01Application {
public static void main(String[] args) {
SpringApplication.run(Producer01Application.class, args);
}
}
此时在重新运行项目,在网页中可以看到已经有了一个服务了,服务名是hello-service,端口号是:8081
同样的方法我们再创建一个服务提供者:
跟上面第一个服务提供者基本都是一样的操作,就是配置文件中端口号要改下:
server.port=8082
#为服务命名
spring.application.name=hello-service
#指定服务注册中心的地址
eureka.client.service-url.defaultZone=http://localhost:1111/eureka/
#服务续约 定义服务续约任务的调用间隔时间,默认30秒
eureka.instance.lease-renewal-interval-in-seconds=30
#服务续约 定义服务失效的时间
eureka.instance.lease-expiration-duration-in-seconds=90
controller层代码:
@RestController
public class ProController {
@RequestMapping(value = "/hello",method = RequestMethod.GET)
public String pro(){
return "this is two";
}
}
运行项目后,再刷新页面,可以看到有了两个服务实例了:
接下来我们就不写服务提供者了,来写一个服务消费者:
之前的步骤都是相同的,我就直接到创建名字这一步了哦
配置信息:
spring.application.name=ribbon-consumer
server.port=9000
eureka.client.service-url.defaultZone=http://localhost:1111/eureka/
主启动类的代码:
@EnableDiscoveryClient
@SpringBootApplication
public class Consumer01Application {
@Bean
@LoadBalanced
//负载均衡
RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(Consumer01Application.class, args);
}
}
service层代码:
@Service
public class HelloService {
@Autowired
RestTemplate restTemplate;
public String helloService(){
return restTemplate.getForEntity("http://HELLO-SERVICE/hello",String.class).getBody();
}
}
controller层代码:
@RestController
public class ConsumerController {
@Autowired
HelloService helloService;
@RequestMapping(value = "/ribbon-consumer", method = RequestMethod.GET)
public String helloConsumer() {
return helloService.helloService();
}
}
刷新刚才的页面:
再来访问这个地址:http://localhost:9000/ribbon-consumer
可以看到:
再刷新一次:
到这里我们可以看到ribbon的负载均衡默用的是轮询策略
这前提是我们两个服务提供者都是正常情况下的,如果有一个服务提供者服务关闭呢?会出现什么情况?
我们先关闭一个服务看看:
接下来我们在访问:http://localhost:9000/ribbon-consumer
多次访问可能出现
接下来我们用到了断路器的组件了。
先在pom文件中导入依赖:
<!--@HystrixCommand注解是由名为javanica的Hystrix contrib库提供的。javanica是一个Hystrix的子项目,用于简化Hystrix的使用-->
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-javanica</artifactId>
<version>RELEASE</version>
</dependency>
接下来在service层代码中添加:
@HystrixCommand(fallbackMethod = "helloFallback")
全部代码如下:
@Service
public class HelloService {
@Autowired
RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "helloFallback")
public String helloService(){
//HELLO-SERVICE/hello hello-service服务下的hello接口
return restTemplate.getForEntity("http://HELLO-SERVICE/hello",String.class).getBody();
}
public String helloFallback(){
return "error";
}
}
启动类代码:
@EnableCircuitBreaker//熔断器
@EnableDiscoveryClient
@SpringBootApplication
public class Consumer01Application {
@Bean
@LoadBalanced
//负载均衡
RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(Consumer01Application.class, args);
}
}
最后我们再写一个消费者,基于feign的负载均衡
配置文件相关信息:
spring.application.name=feign-consumer
server.port=9002
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
service代码:
//hello-service 服务名称
@FeignClient("hello-service")
public interface HelloService {
//hello 服务调用接口
@RequestMapping("/hello")
String hello();
}
controller层代码:
@RestController
public class ConsumerController {
@Autowired
HelloService helloService;
@RequestMapping(value = "/feign-consumer",method = RequestMethod.GET)
public String helloConsumer(){
return helloService.hello();
}
}
启动类代码:
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class Consumer02Application {
public static void main(String[] args) {
SpringApplication.run(Consumer02Application.class, args);
}
}