SpringBoot日记——分布式篇

  思考:什么是分布式?什么是微服务?

  一些概念:RPC-远程过程调用,某台机器想要调用另一台机器所需要的一种服务,及分布式的服务框架,比如dubbo或者SpringCloud。

  铺天盖地的分布式互联网系统,使用较多的是zookeeper+dubbo组合,而Springboot推荐使用全栈Spring,就是Springboot+SpringCloud。

  举例说明一下基本原理:A想要获得数据B,但是有10台机器都可能存放了数据B,那么我要去哪台取数据B呢?A和B中间就有了一个管理站,这个管理站类似一个分配和注册中心,他可以告诉A想要的数据B在哪些机器里,A知道了以后就可以去这些机器里取了。同样B想要把自己数据分享给A,那么可以咨询这个管理站来知道可以分享给谁。

  那么我们说的Dubbo或者SpringCloud就是上边说到的RPC服务框架,而Zookeeper和SpringBoot就可以作为这个管理站点来使用。

  Zookeeper+Dubbo

  官方看文档,或者网搜相关部署,比如:https://www.cnblogs.com/jaycekon/p/SpringBootDubbo.html

  这篇文章主要以这个为主来讲,上边的自己看吧,有需要我再单独补文章~

SpringBoot+SpringCloud

  Cloud与Dubbo的区别,Dubbo解决的就是远程过程调用的RPC服务,而Cloud更全面,它有一整套的分布式需要的对应的解决方案:配置管理、服务发现、熔断、路由、微代理、控制总线、一次性token、全局锁、leader选举、分布式session、集群状态。所以使用Cloud可以更快速的与云平台进行对接。

  SpringCloud五大常用组件:

    • 服务发现-Netflix Eureka
    • 客服端负载均衡-Netflix Ribbon
    • 断路器-Netflix Hystrix
    • 服务网关-Netflix Zuul
    • 分布式配置-SpringCloudConfig

  那么我们来看SpringCloud怎么搞~

  1)、配置-Eureka信息

  首先我们创建几个需要用到的module,一个注册中心,一个服务提供方,一个服务使用方。然后在注册中心进行一下配置:

  这里可以使用编译器中创建Spring Initializr的快捷模式

# 这里我使用了application.yml的配置,看起来会更清晰
server: port: 8761 #启动端口 eureka: instance: hostname: eureka-server #eureka实例主机名-注册中心的名字 client: register-with-eureka: false #不把自己注册到注册中心,因为本身就是作为注册中心的存在 fetch-registry: false #不从eureka上获取注册信息,同上 service-url: defaultZone: http://localhost:8761/eureka #配置默认的启动路径
/**
 * 注册中心
* EnableEurekaServer启动eureka服务
*/ @EnableEurekaServer @SpringBootApplication public class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class, args); } }

  2)、启动主程序,打开浏览器测试一下(先看启动信息,已经启动了该服务):

  2)、配置-provider信息

    1.创建服务并将主程序启动(这是服务中心的服务不要停,也是在启动状态的),然后再来看服务已经注册进去了

import org.springframework.stereotype.Service;

@Service
public class TicketService {

    public String getTicket() {
        return "《大鲨鱼》";
    }
}
service.TicketService
import com.ice.provider.service.TicketService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TicketController {

    @Autowired
    TicketService ticketService;

    @GetMapping("/ticket")
    public String getTicket() {
        return ticketService.getTicket();
    }
}
controller.TicketController
server:
  port: 8001  #提供方的启动端口
spring:
  application:
    name: provider
eureka:
  instance:
    prefer-ip-address: true #注册服务的时候使用服务ip地址
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka
application.yml

    2.来看,如果有多个应用呢?

    修改一下server.port,一个8001,一个8002,分别打包启动。然后再来看注册中心里边(两个都在)

   3)、配置-consumer信息

  同样,先把自己注册到注册中心,然后创建个controller,并启动主程序,检查:

server:
  port: 8200  #提供方的启动端口
spring:
  application:
    name: consumer
eureka:
  instance:
    prefer-ip-address: true #注册服务的时候使用服务ip地址
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka
application.yml
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;


@EnableDiscoveryClient  // 开启发现服务
@SpringBootApplication
public class ConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }

    @LoadBalanced // 启用负载均衡服务
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}
ConsumerApplication
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;

@RestController
public class UserController {

    @Autowired
    RestTemplate restTemplate;

    @GetMapping("/buy")
    public String buyTicket(String name) {
        // 从注册中心获取提供方的信息,http://提供方应用的名字/路径,String类型
        String s = restTemplate.getForObject("http://PROVIDER/ticket", String.class);
        return name + "购买了" + s;
    }
}
controller.UserController

  如此,我们的分布式就说到这里,这么看,不是很难理解吧?

  P.S:我们在上边有一个负载均衡的注解,哪里可以看来有什么作用呢?如果你启动了8001和8002的两个服务,可以通过启动窗口看到(我们有在两个服务中加入不同的打印语句),两个端口分别被调用,轮询式的均衡调用~

  

posted @ 2018-08-28 10:00  碎冰  阅读(12437)  评论(0编辑  收藏  举报