分布式

分布式系统理论

分布式Dubbo+Zookeeper+SpringBoot

什么是分布式系统

分布式系统是由一组通过网络进行通信,为了完成共同的任务而协调工作的计算机节点组成的系统。分布式系统的出现是为了用廉价的、普通的机器完成单个计算机无法完成的计算、存储任务。其目的是利用更多的机器,处理更多的数据

分布式系统(distributed system)是建立在网络之上的软件系统

RPC

RPC【Remote Procedure Call】是指远程过程调用,是一种进程间通信方式,他是一种技术的思想,而不是规范,他允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不是程序员显示编码这个远程远程调用的细节。即程序员无论是调用本地的还是远程的函数,本质上编写的调用代码基本相同

也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据

为什么要用RPC呢,就是无法在一个进程内,甚至一个计算机内通过本地调用的方式完成的需求,比如不同的系统间的通讯,甚至不同的组织间的通讯,由于计算能力需要横向扩展,需要在多台机器组成的集群上部署应用

RPC就是要像调用本地的函数一样去调用远程函数

RPC两个核心模块:通讯,序列化:数据传输需要转换

Dubbo及Zookeeper安装

什么是dubbo

Apache Dubbo 是一款高性能、轻量级的开源Java RPC框架,他提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现

服务提供者(Provider):暴露服务的服务提供放,服务提供者在启动时,向注册中心注册自己提供的服务

服务消费者(Consumer):调用远程服务的服务消费方,服务消费者在启动时,向注册中心订阅自己所需的服务,服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用

注册中心(Registry):注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者

监控中心(Monitor):服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心

安装zookeeper

下载zookeeper apache-zookeeper-3.6.2-bin.tar.gz

https://downloads.apache.org/zookeeper/zookeeper-3.6.2/

运行/bin/zkServer.md

配置CLASSPATH环境变量

变量名为CLASSPATH,变量值为 .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;

/conf/ 复制zoo_sample.cfg 重命名为zoo.cfg

运行/bin/zkServer.md

运行/bin/zkCli.md 连接

安装dubbo-admin

用jdk1.8版本,不要用新的

dubbo本身并不是一个服务软件,其实就是一个jar包,能够帮你的java程序连接到zookeeper,并利用zookeeper消费,提供服务

但是为了让用户更好的管理监控众多的dubbo服务,官方提供了一个可视化的监控程序dubb-admin,不过这个监控即使不装也不影响使用

下载dubbo-admin

https://github.com/apache/dubbo-admin/tree/master

解压进入目录

修改dubbo-admin\src\main\resources\application.properties 指定zookeeper地址

在项目目录下打包dubbo-admin

mvn clean package -Dmaven.test.skip=true

直接在命令行下执行,而不是powershell

PowerShell 窗口下,执行带参数的需要’单引号’包起来才可以

执行dubbo-admin\target下的dubbo-admin-0.0.1-SNAPSHOT.jar(zookeeper的服务一定要打开)

java -jar dubbo-admin-0.0.1-SNAPSHOT.jar

访问http://localhost:7001/ 这时候需要输入登录账户和密码,我们都是默认的root-root

dubbo-admin 是一个监控管理后台~可以查看注册了哪些服务,哪些服务被消费了

Dubbo:jar包

服务注册发现实战

pom文件不生效,解决办法

  • 右击pom文件 add as maven project
  • 或者 project structure Module import module 导入pom文件

新建一个空工程

  • 新建一个spring initializer 命名为 provider-server 勾选web
  • 新建一个spring initializer 命名为 consumer-server 勾选web

provider-service 导入依赖 Dubbo+zookeeper

<!-- https://mvnrepository.com/artifact/org.apache.dubbo/dubbo-spring-boot-starter -->
<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>2.7.8</version>
</dependency>

<!-- https://mvnrepository.com/artifact/com.github.sgroschupf/zkclient -->
<dependency>
    <groupId>com.github.sgroschupf</groupId>
    <artifactId>zkclient</artifactId>
    <version>0.1</version>
</dependency>

<!--日志会冲突-->
<!-- https://mvnrepository.com/artifact/org.apache.curator/curator-framework -->
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-framework</artifactId>
    <version>5.1.0</version>
</dependency>


<!-- https://mvnrepository.com/artifact/org.apache.curator/curator-recipes -->
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>5.1.0</version>
</dependency>


<!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.6.2</version>
    <!--排除这个slf4j-log4j12-->
    <exclusions>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </exclusion>
    </exclusions>
</dependency>

provider-server

配置

server.port=8001

#服务应用名字
dubbo.application.name=provicer-server
#注册中心地址
dubbo.registry.address=zookeeper:/127.0.0.1:2181
#哪些服务要被注册
dubbo.scan.base-packages=com.company.service
package com.company.service;

public interface TicketService {
    String getTicket();
}
package com.company.service;


import org.apache.dubbo.config.annotation.Service;
import org.springframework.stereotype.Component;
//zookeeper:服务注册与发现
@Service  //可以被扫描到,在项目以启动就自动注册到注册中心
@Component//使用了Dubbo后尽量不要用service注解
public class TicketServiceImpl implements TicketService{

    @Override
    public String getTicket() {
        return "明";
    }
}

启动出错:解决

  • 配置文件配置超时时间

  • 
    dubbo.config-center.timeout=10
    
  • windows 查看端口被占用情况

  • netstat -aon|findstr "8080"

  • 强制终止

  • taskkill /f /pid 进程号

启动成功后,

运行java -jar dubbo-xx.jar

访问localhost:7001/ 在服务治理下/服务 可以看到TicketService

注意Dubbo注解不要导错了

服务端

导入依赖

<!-- https://mvnrepository.com/artifact/org.apache.dubbo/dubbo-spring-boot-starter -->
<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>2.7.8</version>
</dependency>

<!-- https://mvnrepository.com/artifact/com.github.sgroschupf/zkclient -->
<dependency>
    <groupId>com.github.sgroschupf</groupId>
    <artifactId>zkclient</artifactId>
    <version>0.1</version>
</dependency>

<!--日志会冲突-->
<!-- https://mvnrepository.com/artifact/org.apache.curator/curator-framework -->
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-framework</artifactId>
    <version>5.1.0</version>
</dependency>


<!-- https://mvnrepository.com/artifact/org.apache.curator/curator-recipes -->
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>5.1.0</version>
</dependency>


<!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.6.2</version>
    <!--排除这个slf4j-log4j12-->
    <exclusions>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </exclusion>
    </exclusions>
</dependency>

配置

server.port=8002


#消费者去哪里拿服务需要暴露自己的名字
dubbo.application.name=consumer-server
#注册中心地址
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.config-center.timeout=10

消费

package com.company.service;

import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;

@Service //放到容器中
public class UserService {

    //想拿到provider提供的票
    @Reference //引用,pom坐标,可以定义路径相同的接口名
    TicketService ticketService;

    public void buyTicket(){
        String ticket = ticketService.getTicket();
        System.out.println("在注册中心拿到=》"+ticket);
    }
}

总结

前提:zookeeper服务已开启

服务者提供服务

  • 导入依赖
  • 配置注册中心的地址,以及服务发现名,和要扫描的包
  • 在想要被注册的服务上面,增加一个注解@service (不是Spring的注解)(新版的是@DubboService)

消费者消费

  • 导入依赖
  • 配置注册中心的地址,配置自己的服务名
  • 从远程注入服务~@Reference

微服务架构问题

分布式架构遇到的四个核心问题

  • 这么多服务,客户端如何去访问
  • 这么多服务,服务之间如何通信
  • 这么多服务,如何治理
  • 服务挂了,怎么办

解决方案

  • SpringCloud,是一套生态,就是来解决以上分布式架构的4个问题

    SpringCloud是基于SpringBoot

1.SpringCloud NetFlix

​ Api网关 zuul组件

​ Feign -》HttpClient-》Http的通信方式,同步并阻塞

​ 服务注册与发现,Eureka

​ 熔断机制,Hystrix

2.Apache Dubbo zookeeper

​ Api:没有,要么找第三方组件,要么自己实现

​ Dubbo是一个高性能的基于Java实现的RPC通信框架

​ 服务注册与发现,zookeeper:动物园管理者(Hadoop,Hive)

3.SpringCloud Alibaba 一站式解决方案

目前,又提出一种方案:

  • 服务网格:下一代微服务标准 Server Mesh
  • 代表解决方案:istio(未来可能需要掌握)

一通百通:

  • API网关,服务路由
  • HTTP,RPC框架,异步调用
  • 服务注册与发现,高可用
  • 熔断机制,服务降级

不要停止学习的脚步,程序员学无止境

posted @ 2020-11-10 20:42  yourText  阅读(173)  评论(2编辑  收藏  举报