Springboot与Springcloud分布式
2019-07-20 本文已影响46人
椰子奶糖
SpringCloud概念
- 官方的定义是这样的:
Spring Cloud provides tools for developers to quickly build some of the common
patterns in distributed systems (e.g. configuration management, service discovery,
circuit breakers, intelligent routing, micro-proxy, control bus, one-time tokens, global
locks, leadership election, distributed sessions, cluster state). Coordination of
distributed systems leads to boiler plate patterns, and using Spring Cloud
developers can quickly stand up services and applications that implement those
patterns. They will work well in any distributed environment, including the
developer’s own laptop, bare metal data centres, and managed platforms such as
Cloud Foundry.
- 大概意思是
Spring Cloud为开发人员提供了快速构建分布式系统中的一些常见模式的工具(例如配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性令牌、全局锁、领导层选举、分布式会话、集群状态)。分布式系统的协调导致了锅炉板模式,使用Spring Cloud开发人员可以快速建立实现这些模式的服务和应用程序。它们在任何分布式环境中都能很好地工作,包括开发人员自己的笔记本电脑、裸机数据中心和云计算等托管平台 - 有道翻译结果中有些词有点难理解,比如这个锅炉板模式是啥意思
- 在我的理解应该翻译成样板模式,类似一些可以复用的样板代码,而SpringCloud可以快速搭建出这样的样板框架,从而使得开发者可以快速搭建类似的服务和应用。
SpringCloud分布式开发五大常用组件
- 服务发现——Netflix Eureka
- 客服端负载均衡——Netflix Ribbo
- 断路器——Netflix Hystrix
- 服务网关——Netflix Zuul
- 分布式配置——Spring Cloud Config
分布式Demo
- 参照之前Dubbo+zookeeper的例子,还是使用买票的例子
1.建立三个工程分别是:注册中心server,服务提供者provider和服务消费者consumer;
-
server需要引入Eureka Server依赖,后两者需要Eureka Discovery Client依赖
image.png
2.配置Server,这里用的是yaml文件写的,需要注意的是Server不需要将自己注册到eureka上,也不需要从eureka上获取信息
server:
port: 8761
eureka:
instance:
hostname: eureka-server #eureka实例的主机名
client:
register-with-eureka: false #不把自己注册到eureka上
fetch-registry: false #不从eureka上获取注册信息
service-url:
defaultZone: http://localhost:8761/eureka/
3.编写provider
- 先要配置provider,端口号是可以变的,与server不同的是
- 它需要将自己注册到eureka上,
- 也需要从eureka上获取信息,
- 注册服务的时候使用服务的ip地址
- 还有一点它需要指定自己的名字是什么:
server:
port: 8002
spring:
application:
name: provider-ticket
eureka:
instance:
prefer-ip-address: true #注册服务的时候使用服务的ip地址
client:
service-url:
defaultZone: http://localhost:8761/eureka/
- Service层
import org.springframework.stereotype.Service;
/**
* Created by CHEN on 2019/7/19.
*/
@Service
public class TicketService {
public String getTicket(){
System.out.println("这是8002");
return "《这是两张电影票》";
}
}
- controller层
import ch.service.TicketService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by CHEN on 2019/7/19.
*/
@RestController
public class TicketController {
@Autowired
TicketService ticketService;
@GetMapping("/ticket")
public String getTicket(){
return ticketService.getTicket();
}
}
-
测试运行是否成功,成功后web访问 http://localhost:8761/可以看到
image.png
-
我是稍微改了以下打了两个包,所以由两个不同端口同名的服务,主要用于测试负载均衡用的
编写consumer
-消费者的服务的编写比较简单,首先配置:
server:
port: 8200
spring:
application:
name: consumer-user
eureka:
instance:
prefer-ip-address: true #注册服务的时候使用服务的ip地址
client:
service-url:
defaultZone: http://localhost:8761/eureka/
- 接下来,需要拿到RestTemplate,我们需要通过它来访问服务提供者拿到方法的结果
@LoadBalanced//启动负载均衡机制
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
-就可以在controller中使用了:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* Created by CHEN on 2019/7/19.
*/
@RestController
public class UserController {
@Autowired
RestTemplate restTemplate;
@GetMapping("/buy")
public String buyTicket(String name){
//调用提供者的方法,可以看出他是通过网络访问的
String ticket = restTemplate.getForObject("http://PROVIDER-TICKET/ticket", String.class);
return name+"买了:"+ticket;
}
}
- 编写完毕后,运行,再次查看http://localhost:8761/

-
运行效果:
image.png
image.png
-
所谓负载均衡就是调用访问次数比较少的服务器,在实验中的效果就是依次循环调用