分布式

springcloud

springCloud是分布式微服务整体解决方案。
Spring Cloud 为开发者提供了在分布式系统(配置管理,[服务发现,熔断,路由,微代理,控制总线,一次性token,全局琐,leader选举,分布式session,集群状态)中快速构建的工具,使用Spring Cloud的开发者可以快速的启动服务或构建应用、同时能够快速和云平台资源进行对接。

SpringCloud分布式开发五大常用组件:

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

springCloud体验
eureka 服务发现与注册
RestTemplate 发送http请求

远程调用

dubbo+zookeep体验
dubbo是一个远程调用服务的分布式框架,可以实现远程通讯、动态配置、地址路由等等功能。它可以通过集成注册中心,来动态地治理服务发布和服务调用。相当于把服务注册和发布推送的功能分摊给了(zookeeper)注册中心
Dubbo实现服务调用是通过RPC的方式,即客户端和服务端共用一个接口(将接口打成一个jar包,在客户端和服务端引入这个jar包),客户端面向接口写调用,服务端面向接口写实现,中间的网络通信交给框架去实现
Zookeeper 是 Apacahe Hadoop 的子项目,是一个树型的目录服务,支持变更推送,适合作为 Dubbo 服务的注册中心。【参考

  • 安装zookeep
    可以通过docker容器快速安装
  • 引入需要的依赖
<!--引入dubbo-->
<dependency>
    <groupId>com.alibaba.boot</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>0.1.0</version>
</dependency>

<!--引入zookeeper客户端工具-->
<!-- https://mvnrepository.com/artifact/com.101tec/zkclient -->
<dependency>
    <groupId>com.101tec</groupId>
    <artifactId>zkclient</artifactId>
    <version>0.10</version>
</dependency>
  • 服务提供端
----服务接口
package com.xiaoai.ticket.service;
public interface TicketService {
    public String getTicket();
}

----服务接口实现
@Component
@com.alibaba.dubbo.config.annotation.Service  // 该注解即把服务发布出去
public class TicketServiceImpl implements TicketService{
    @Override
    public String getTicket() {
        return "《厉害了,我的国》";
    }
}

----配置文件
dubbo:
  application:
    name: provider-ticket
  registry:
    address: zookeeper://192.168.121.128:2181
  scan:
    base-packages: com.xiaoai.ticket.service
  • 服务消费端
----创建一样的接口
package com.xiaoai.ticket.service;

public interface TicketService {
    public String getTicket();
}

----相关服务中调用远程服务
@Service
public class UserService {

    @Reference  // 引入相关远程服务
    TicketService ticketService;

    public void hello(){
        String ticket = ticketService.getTicket();
        System.out.println("拿到票:"+ticket);
    }
}

----配置文件
dubbo:
  application:
    name: consumer-user
  registry:
    address: zookeeper://192.168.121.128:2181

使用dubbo注意在启动器中开启dubbo支持:【@EnableDubbo】

  • 测试
----在客户端调用远程服务
@RunWith(SpringRunner.class)
@SpringBootTest
class ConsumerUserApplicationTests {

	@Autowired
	UserService userService;

	@Test
	void contextLoads() {
	      userService.hello();
	}
}

----结果
拿到票:《厉害了,我的国》

dubbo+nacos+zuul体验
dubbo 远程调用
nacos 配置中心、服务发现
zuul 网关路由

例子:应用项目去调用消费服务项目,消费服务项目去调用提供服务项目

  • 引入依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>0.9.0.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    <version>0.9.0.RELEASE</version>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-dubbo</artifactId>
    <version>2.1.1.RELEASE</version>
</dependency>

在启动类中添加注解【@EnableDiscoveryClient】开启服务发现
服务接口可单独提取作api项目,在实现项目中引入api项目实现相关接口即可,在其他项目需要另一个项目的服务时直接引入api项目即可。

----服务接口
package com.xiaowei.service2.api;

public interface ProviderService {
    public String service();
}

----服务接口实现
package com.xiaowei.service2.service;

@org.apache.dubbo.config.annotation.Service
public class ProviderServiceImpl implements ProviderService {
    @Override
    public String service() {
        return "Provider Invoke【提供服务端service2-server】执行...";
    }
}

----配置文件
server:
  port: ${port:56040} #启动端口 命令行注入
  servlet:
    context-path: /service2

spring:
  application:
    name: service2
  main:
    allow-bean-definition-overriding: true
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848 #
        namespace: 62f4e350-bb14-4271-9b4e-6ba2005f3f1c
        cluster-name: DEFAULT

      # 连接配置中心配置对应配置文件,通过配置中心可获取项目相关配置,
      # 该项目暂未有其他配置,只是先配置连接 即可不配置
#      config:
#        server-addr: 127.0.0.1:8848 # 配置中心地址
#        file-extension: yaml # 配置文件后缀 默认是context-path.后缀来查找配置中心的文件
#        namespace: 62f4e350-bb14-4271-9b4e-6ba2005f3f1c # 开发环境
#        group: XIAOAI_MICROSERVICE_GROUP # 业务组,可理解为那个项目

dubbo:
  scan:
    base-packages: com.xiaowei.service2.service
  protocol:
    name: dubbo
    port: ${dubbo_port:20891}
  registry:
    address: nacos://127.0.0.1:8848
    application:
      qos-enable: false
    consumer:
      check: false
  • 消费服务端
----服务接口
package com.xiaowei.service1.api;

public interface ConsumerService {
    public String service();
}

----服务接口实现
package com.xiaowei.service1.service;

@org.apache.dubbo.config.annotation.Service
public class ConsumerServiceImpl implements ConsumerService {

    @org.apache.dubbo.config.annotation.Reference
    private ProviderService providerService;

    @Override
    public String service() {
        return "Consumer Invoke【消费服务端service1-server】执行...调用【提供服务端】:\n"+providerService.service();
    }
}

----配置文件
server:
  port: ${port:56030} #启动端口 命令行注入
  servlet:
    context-path: /service1

spring:
  application:
    name: service1
  main:
    allow-bean-definition-overriding: true
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848 #
        namespace: 62f4e350-bb14-4271-9b4e-6ba2005f3f1c
        cluster-name: DEFAULT

      # 连接配置中心配置对应配置文件,通过配置中心可获取项目相关配置,
      # 该项目暂未有其他配置,只是先配置连接 即可不配置
#      config:
#        server-addr: 127.0.0.1:8848 # 配置中心地址
#        file-extension: yaml # 配置文件后缀 默认是context-path.后缀来查找配置中心的文件
#        namespace: 62f4e350-bb14-4271-9b4e-6ba2005f3f1c # 开发环境
#        group: XIAOAI_MICROSERVICE_GROUP # 业务组,可理解为那个项目

dubbo:
  scan:
    base-packages: com.xiaowei.service1.service
  protocol:
    name: dubbo
    port: ${dubbo_port:20881}
  registry:
    address: nacos://127.0.0.1:8848
    application:
      qos-enable: false
    consumer:
      check: false
  • 应用端
----应用端
package com.xiaowei.application.rest;

@RestController
@RequestMapping("/application1")
public class ApplicationController {

    @org.apache.dubbo.config.annotation.Reference
    private ConsumerService consumerService;

    @GetMapping(value = "/service")
    public String service(){
        String target=consumerService.service();
        return "application Invoke【应用端application-1】执行...调用【消费服务端】:\n"+target;
    }
}

----配置文件
server:
  port: ${port:56020} #启动端口 命令行注入
  servlet:
    context-path: /application1

spring:
  application:
    name: application1
  main:
    allow-bean-definition-overriding: true
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848 #
        namespace: 62f4e350-bb14-4271-9b4e-6ba2005f3f1c
        cluster-name: DEFAULT

      # 连接配置中心配置对应配置文件,通过配置中心可获取项目相关配置,
      # 该项目暂未有其他配置,只是先配置连接 即可不配置
#      config:
#        server-addr: 127.0.0.1:8848 # 配置中心地址
#        file-extension: yaml # 配置文件后缀 默认是context-path.后缀来查找配置中心的文件
#        namespace: 62f4e350-bb14-4271-9b4e-6ba2005f3f1c # 开发环境
#        group: XIAOAI_MICROSERVICE_GROUP # 业务组,可理解为那个项目

以上即可通过dubbo实现正常服务调用了
可以加入网关服务,完成路由转发。网关:将两个使用不同协议的网络段连接bai在一起。可以看成将两个不同项目的服务进行连接。

  • zuul网关
----启动器开启网关代理
@SpringBootApplication
@EnableDiscoveryClient  //开启服务发现
@EnableZuulProxy   // 开启网关代理
public class ApiGatewayBootstrap {
    public static void main(String[] args) {
        SpringApplication.run(ApiGatewayBootstrap.class,args);
    }
}

----配置文件
server:
  port: 8000 #启动端口 命令行注入

spring:
  application:
    name: api-gateway
  main:
    allow-bean-definition-overriding: true
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848 #
        namespace: 62f4e350-bb14-4271-9b4e-6ba2005f3f1c
        cluster-name: DEFAULT
     
       # 由于需要用到配置中心的配置,因此需要配置nacos相关信息
      config:
        server-addr: 127.0.0.1:8848 #
        file-extension: yaml
        namespace: 62f4e350-bb14-4271-9b4e-6ba2005f3f1c
        group: XIAOAI_MICROSERVICE_GROUP

----配置中心配置文件:application1.yml
zuul:
    routes:
        application1: 
            stripPreFix: false
            path: /application1/**  # 把以application1开头的请求路径都转发到服务名为application1的应用中
  • 测试
----访问:http://localhost:56020/application1/application1/service
application Invoke【应用端application-1】执行...调用【消费服务端】:
Consumer Invoke【消费服务端service1-server】执行...调用【提供服务端】:
Provider Invoke【提供服务端service2-server】执行...

----访问:http://localhost:8000/application1/application1/service
application Invoke【应用端application-1】执行...调用【消费服务端】:
Consumer Invoke【消费服务端service1-server】执行...调用【提供服务端】:
Provider Invoke【提供服务端service2-server】执行...

posted @ 2021-01-17 14:37  小艾影  阅读(170)  评论(0编辑  收藏  举报