SpringBoot中的分布式简单应用(Dubbo和Zookeeper、Spring Cloud)

本文对比分析了Dubbo与SpringCloud在微服务架构中的应用,Dubbo专注于解决服务间的远程调用问题,而SpringCloud则提供了一整套分布式系统的解决方案,包括服务发现、负载均衡、断路器等功能。
Dubbo架构工作图

Dubbo架构结构图

Container:服务容器
Provider:服务提供者
Registry:注册中心
Consumer服务消费者
Monitor监控中心

register服务信息
subscribe所需要的服务
notify长链接

Container在启动时负责加载和运行ProviderProvider在启动时将自己能提供的 register服务信息 注册到RegistryConsumer服务消费者在启动时从Registry订阅 subscribe所需要的服务。注册中心将其所需的服务列表返回给Consumer。服务如果有变更,Registry基于 notify长链接 的方式将变更推送给Consumer。如果Provider要调用,从提供者的地址列表中,基于负载均分机制找到某个提供者的位置,来调用Provider的服务。如果调用失败,在地址列表中再找另一个Provider继续调用,直到调用成功。Dubbo提供监控机制,调用次数、调用时间等信息每分钟给Monitor来发送一次。以此来做到一系列的监控。

在Linux Docker安装Zookeeper

[root@localhost ~]# docker pull zookeeper

启动一个Zookeeper服务器实例

[root@localhost ~]# docker run --name zk01 -p 2181:2181 --restart always -d zookeeper

IDEA工程

创建两个工程:

  1. provider-ticket:服务提供者
  2. consumer-user:服务消费者

  • 创建Empty Project空工程springboot-06-dubbo
  • 创建provider-ticket工程作为卖票服务
  • 在com.atguigu.ticket.service包中创建service.TickerService接口
  • 在com.atguigu.ticket.service包中创建接口的实现TicketServiceImpl
  • 创建consumer-user工程作为消费者
  • 在com.atguigu.user.service创建service.UserService

思考:在UserService中如何使用TicketServiceImpl?

  • 首先需要使用Dubbo将provider-ticket服务提供者注册到注册中心
  • consumer-user要使用provider-ticket服务,consumer-user从注册中心订阅配置的服务,拿到服务者地址列表,consumer-user可以来调用provider-ticket服务。其中的调用环节也是Dubbo完成的。

  1. provider-ticket服务提供者注册到注册中心
    • 在pom.xml中引入dubbo和zkclient相关依赖
      <dependency>
      	<groupId>com.alibaba.boot</groupId>
      	<artifactId>dubbo-spring-boot-starter</artifactId>
      	<version>0.1.0</version>
      </dependency>
      
      <dependency>
      	<groupId>com.github.sgroschupf</groupId>
      	<artifactId>zkclient</artifactId>
      	<version>0.1</version>
      </dependency>
      
    • 在application.properties中配置dubbo的扫描包和注册中心地址
      # 当前应用的名字
      dubbo.application.name=provider-ticket
      # 注册中心的地址
      dubbo.registry.address=zookeeper://192.168.200.130:2181
      # 扫描哪些包,将其服务发布出去
      dubbo.scan.base-packages=com.atguigu.ticket.service
      
    • 使用@Service发布服务。在com.atguigu.ticket包的TicketServiceImpl编写以下代码:
      @Component //加在Spring容器中
      @Service //将服务发布出去,是com.alibaba.dubbo.config.annotation.Service下的注解
      public class TicketServiceImpl implements TicketService {
      	@Override
      	public String getTicket() {
      		return "《厉害了,我的国》";
      	}
      }
      
      这样就将服务发布出去了。
  2. consumer-user消费者进行测试
    • 在pom.xml中引入dubbo和zkclient相关依赖
      <dependency>
      	<groupId>com.alibaba.boot</groupId>
      	<artifactId>dubbo-spring-boot-starter</artifactId>
      	<version>0.1.0</version>
      </dependency>
      
      <dependency>
      	<groupId>com.github.sgroschupf</groupId>
      	<artifactId>zkclient</artifactId>
      	<version>0.1</version>
      </dependency>
      
    • 配置dubbo的注册中心地址
      # 当前应用的名字
      dubbo.application.name=consumer-user
      # 注册中心的地址
      dubbo.registry.address=zookeeper://192.168.200.130:2181
      
    • 引用服务
      • 需要存在一份一模一样的TicketService,将其复制到consumer-user工程的com.atguigu.ticket.service包中。
      • 在com.atguigu.user.service包的UserService编写以下代码:
        @Service
        public class UserService{
        	@Reference //远程引用
        	TicketService ticketService;
        	public void hello(){
        		String ticket = ticketService.getTicket();
        		System.out.println("买到票了:"+ticket);
        	}
        } 
        
      • 在test文件夹中的com.atguigu.user包下的ConsumerUserApplicationTests类中编写以下代码:
        @RunWith(SpringRunner.class)
        @SpringBootTest
        public class ConsumerUserApplicationTests {
        	@Autowired
        	UserService userService;
        	@Test
        	public void contextLoads() {
        		userService.hello();
        	}
        }
        
  3. 启动ProviderTicketApplicationConsumerUserApplicationTests.contextLoads(),控制台会得到:
    买到票了:《厉害了,我的国》


Spring Boot和Spring Cloud

思考:Spring Cloud和Dubbo的区别?

  • Dubbo是分布式服务框架,主要解决服务之间如A服务,B服务,C服务远程过程调用问题,也就是他们之间的RPC。
  • 而Spring Cloud是分布式整体解决方案,也就是说在分布式系统里需要考虑的基本上所有问题,Spring Cloud都有对应的解决方案。如在分布式系统(配置管理,服务发现,熔断,路由,微代理,控制总线,一次性token,全局锁,leader选举,分布式session,集群状态)中快速构建的工具。
  • Spring Cloud分布式开发五大常用组件
    • 服务发现——Netflix Eureka
    • 客服端负载均衡——Netflix Ribbon
    • 断路器——Netflix Hystrix
    • 服务网关——Netflix Zuul
    • 分布式配置——Spring Cloud Config
  • 举例:
    • 用Zookeeper和Dubbo,A服务和B服务要注册到注册中心里,注册中心相当于Netflix Eureka
    • A服务和B服务之间之间互连互调,假设A服务部署三个实例,B服务也部署了三个实例,A服务要调用哪台机器上的B服务,用到Netflix Ribbon进行负载均衡。
    • 当A服务调B服务时,B服务也调了C服务,C服务也调了D服务,突然C服务出现问题,导致连不通服务,前序进行漫长等待,此时可以引入Netflix Hystrix快速响应失败,不让用户过长等待。
    • Netflix Zuul对请求进行过滤。
    • Spring Cloud Config管理服务的配置。

IDEA工程

创建三个模块:

  1. eureka-server:注册中心服务器
  2. provider-ticket:服务提供者
  3. consumer-user:服务消费者

  • 创建Empty Project空工程springboot-06-springcloud
  • 创建eureka-server模块,选中Cloud Discovery中的Eureka Server注册中心服务器模块
  • 创建provider-ticket模块,选中Cloud Discovery中的Eureka Discovery服务注册和发现模块
  • 创建consumer-user模块,选中Cloud Discovery中的Eureka Discovery服务注册和发现模块
  • 在com.atguigu.providerticket.service包中创建TickerService接口
  • 在com.atguigu.providerticket.controller包中创建TicketController
  • 在com.atguigu.consumeruser.controller包中创建UserController

  1. eureka-server注册中心服务器进行配置
    • 在application.yml中进行配置
      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/
      
    • 在com.atguigu.eurekaserver包的EurekaServerApplication添加注解:
      @EnableEurekaServer
    • 启动注册中心,输入地址http://localhost:8761/进如注册中心界面,关注其中一行Instances currently registered with Eureka(当前注册在服务中心的实例)
  2. 配置provider-ticket服务提供者
    • 在com.atguigu.providerticket.service包的TickerService编写以下代码:
      @Service
      public class TicketService {
      	public String getTicket(){
      		System.out.println("8002");
      	 	return "《厉害了,我的国》";
      	}
      }
      
    • 在com.atguigu.providerticket.controller包的TicketController编写以下代码:
      @RestController
      public class TicketController {
      	@Autowired
      	TicketService ticketService;
      
      	@GetMapping("/ticket")
      	public String getTicket(){
      		return ticketService.getTicket();
      	}
      }
      
    • 在application.yml中进行配置
      server:
      	port: 8002
      spring:
      	application:
      		name: provider-ticket
      eureka:
      	instance:
      		prefer-ip-address: true # 注册服务的时候使用服务的ip地址
      	client:
      		service-url:
      			defaultZone: http://localhost:8761/eureka/
      
  3. 配置consumer-user服务消费者
    • 在com.atguigu.consumeruser.controller包的UserController编写以下代码:
      @RestController
      public class UserController {
      	@Autowired
      	RestTemplate restTemplate;
      
      	@GetMapping("/buy")
      	public String buyTicket(String name){
      		String s = restTemplate.getForObject("http://PROVIDER-TICKET/ticket", String.class);
      		return name+"购买了"+s;
      	}
      }
      
    • 在application.yml中进行配置
      spring:
      	application:
      		name: consumer-user
      server:
      	port: 8200
      eureka:
      	instance:
      		prefer-ip-address: true # 注册服务的时候使用服务的ip地址
      client:
      	service-url:
      		defaultZone: http://localhost:8761/eureka/
      
    • 在com.atguigu.eurekaserver包的EurekaServerApplication编写以下代码:
      @EnableDiscoveryClient //开启发现服务功能
      @SpringBootApplication
      public class ConsumerUserApplication {
      
      	public static void main(String[] args) {
      		SpringApplication.run(ConsumerUserApplication.class, args);
      	}
      
      	@LoadBalanced //使用负载均衡机制
      	@Bean
      	public RestTemplate restTemplate(){
      		return new RestTemplate();
      	}
      }
      
  4. 启动EurekaServerApplicationProviderTicketApplicationConsumerUserApplication,访问http://localhost:8200/buy?name=张三会得到张三购买了《厉害了,我的国》这段文字
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值