大家好,我是melo,一名大二上软件工程在读生,经历了一年的摸滚,现在已经在工作室里边准备开发后台项目啦。

这篇文章我们不谈数据结构了,来谈谈入门分布式踩过的坑。感觉到了分布式这一层,由于技术更新迭代很快,我们似乎很难接触到第一手材料了(就连官方文档都没有实时更新,很多不适用)。几经摸索,看视频,翻文档,找博客,终于把Dubbo+zookeeper的小demo给成功跑起来了,写下这篇是因为里边有好多的坑,具体我都写在代码的注释里边了,希望可以帮到更多小伙伴,少踩一点坑,专心搞技术!

大型互联网项目架构目标

衡量网站的性能指标:

•响应时间:指执行一个请求从开始到最后收到响应数据所花费的总体时间。

•并发数:指系统同时能处理的请求数量。

•并发连接数:指的是客户端向服务器发起请求,并建立了TCP连接。每秒钟服务器连接的总TCP数量

•请求数:也称为QPS(Query Per Second) 指每秒多少请求.

•并发用户数:单位时间内有多少用户

•吞吐量:指单位时间内系统能处理的请求数量。

•QPS:Query Per Second 每秒查询数。

•TPS:Transactions Per Second 每秒事务数。

•一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程。客户机在发送请求时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数。

•一个页面的一次访问,只会形成一个TPS;但一次页面请求,可能产生多次对服务器的请求,就会有多个QPS

集群和分布式

传统

  • 集群: 很多人干同一件事情

很多台服务器,上边负责同一个模块

  • 分布式 : 很多人干不同的事情,合起来是一件大事情

很多台服务器,上边负责不同的小模块,最后合成一个大模块



​

  • 集群和分布式,往往是同时存在的

高可用性

  • 一个服务器挂了,不会影响另一个服务器,可以保证服务一直处于可用状态

高伸缩性

  • 由于把各个模块尽量抽离开了,降低了彼此之前的耦合关系,所以比如要给E模块加多几个,可用直接加不会影响其他模块

高可扩展性

  • 类似开闭原则,因为耦合度不高,所以扩展起来不是很难

架构演变

假设项目由 ABCD基础模块组成 E是公共模块

单体架构

  • 一个服务器上,放着一整个项目 ABCDE

垂直架构

  • 把项目拆成独立(互相没有关联)的两个模块 如 AB CD , 此时的E呢,因为两个服务器没有关联,所以E就不得不部署多次.即 ABE CDE 两台服务器

缺点

  • 公共模块在每个服务器上都需要用到

分布式架构

  • 垂直架构看起来已经是 不同服务器干不同的事情了, 不过还有一个公共模块E,在两个服务器中都出现过,我们要优化的话,可以多加一台服务器,单独放E

远程调用E(RPC)

  • 用到 HTTP REST风格等(Dubbo都帮我们封装好了)

缺点

  • E一但发生了改变,所有调用他的地方都需要去改变

SOA架构

没有什么是再多加一层解决不了的,加一个中间商ESB

微服务架构(待深入)

Dubbo的架构



节点角色说明:

•Provider暴露服务的服务提供方

•Container:服务运行容器

•Consumer:调用远程服务的服务消费方

•Registry:服务注册与发现的注册中心

•Monitor:统计服务的调用次数和调用时间的监控中心

快速入门

Zookeeper下载

官网:https://zookeeper.apache.org/releases.html

我选择的是这个版本,带有bin目录的

Windows

  1. 直接解压出来
  2. 将conf目录下的zoo_sample.cfg复制一份,改名为zoo.cfg(因为默认配置文件是这个名字)
  3. 然后退回安装目录,新建一个空的data 和 log

4 . 进入conf中修改zoo.cfg配置文件,将dataDir=/tmp/zookeeper 修改成 zookeeper 安装目录所在的 data 文件夹,再添加一条添加数据日志的配置(需要根据自己的安装路径修改)。



5 . 双击 bin目录下的 zkServer.cmd 启动程序:



6 . 控制台显示 bind to port 0.0.0.0/0.0.0.0:2181,表示服务端启动成功!



7 . 双击同目录下的zkCli.cmd 启动客户端



出现 Welcome to Zookeeper!,表示我们成功启动客户端。

注意

当需要一直启动zookeeper时,这两个cmd不能关掉不能关掉不能关掉!!!!!!!要保持运行

Linux

tar -zxvf (你下载的压缩包名称)

cd (你的安装目录)

cd conf/

cp zoo_sample.cfg zoo.cfg

vimzoo.cfg

此处需要按照上边一样修改,注意需要根据自己的安装路径修改 , 同样也得创建data和log,修改端口等​

cd ..

cd bin/

sh zkServer.sh start

sh zkCli.sh

​

  • 如果下载的版本不一样,可能需要自行查看一下帮助命令

详细配置(SpringBoot)

多模块开发

此处其实用到了三个模块,一个是公共接口模块,一个是provider模块,一个是consumer模块

其中后两个都共同去依赖公共模块

而provider又依赖consumer模块

想要完整源码的话可以评论区联系一下博主

特别注意

我们两个模块都要去@import com.example.dubbo_interface.service.StuService;

  • 那这里就意味着什么,别的项目得能找到这个包啊,要怎么把公共接口dubbo_interface里边的包暴露出来,可供别人调用呢,这里是用到了maven的install命令,把dubbo_interface这一模块打包到公共仓库去了,这样别的项目就可以引用里边的内容了!

如果对maven这一块还不太熟悉的话,具体可以参照这篇 maven(先给自己挖个坑,整理好了会发出来的)


以下一切配置都完成了之后,记得先打开zookeeper!打开zookeeper!打开zookeeper!

provider提供服务端

yml文件

dubbo:
application:
#配置应用的名称(应用可以是提供者也可以是消费者)
name: dubbo_service
#协议中心
protocol:
#固定的, 是只有provider才需要吗?
name: dubbo
port: 20882
#指定注册中心的位置,127.0.0.1是ip地址,2181是端口号
registry:
address: zookeeper://127.0.0.1:2181
######这里是关键,很多教程没有配置,导致zookeeper连接不上
timeout: 50000
#要暴露的服务所在的包(配置扫包)
#也可以在注解那里扫包
# scan:
# base-packages: com.example.dubbo_service.service #指定该项目模块启动的端口,不可与其他项目端口重复
server:
port: 8081

具体Service服务端

package com.example.dubbo_service.service;

import com.example.dubbo_interface.service.StuService;
import org.apache.dubbo.config.annotation.DubboService; //暴露服务
@DubboService
public class StuServiceImpl implements StuService { @Override
public String login() {
return "111";
}
}

引入Dubbo依赖和控制zookeeper的客户端

这里使用的是2.7.8版本,搭配2.5.5版本的Springboot

注意依赖接口模块

<!--依赖接口项目-->
<dependency>
<groupId>com.example</groupId>
<artifactId>dubbo_interface</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- Dubbo Spring Boot Starter -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.8</version>
</dependency>
<!--curator依赖-->
<!--Curator提供了一套Java类库, 可以更容易的使用ZooKeeper。 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>5.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>5.1.0</version>
</dependency>

启动类

@EnableDubbo注解一般写在启动类上,默认会扫描当前注解所在类的包路径下的所有@Dubboservice标注的组件,如果需要自定义扫描注册的bean(服务实现),可以使用@DubboComponentScan或扫描属性实现。另外,@EnableDubbo注解等效于在配置文件中使用dubbo.scan.base-packages一步到位(开启dubbo功能+扫描dubbo的服务实现bean)

package com.example.dubbo_service;

import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; //开启基于注解的Dubbo功能,同时扫描要暴露的服务端所在的位置
@EnableDubbo(scanBasePackages = "com.example.dubbo_service.service")
@SpringBootApplication
public class DubboServiceApplication { public static void main(String[] args) {
SpringApplication.run(DubboServiceApplication.class, args);
} }

consumer消费者端

注意,其不同于传统的service,这里为了能独立启动,也要设置成web项目那种(再借助Springboot启动)

yml文件

dubbo:
application:
#指定当前服务/应用的名字(同样的服务名字相同,不要和别的服务同名)
name: dubbo_controller
## consumer不需要这个通信协议,因为consumer无需通过Dubbo来远程调用
# protocol:
# name: dubbo
## port: 20881
#指定注册中心的位置,127.0.0.1是ip地址,2181是端口号
registry:
address: zookeeper://127.0.0.1:2181
######这里是关键,很多教程没有配置,导致zookeeper连接不上
timeout: 50000
##发现按照官网只配consumer的话,也还是连不到zookeeper的
consumer:
##后来发现这里就等效于DubboReference注解那里的timeout设置
timeout: 3000
##此处是用在暴露扫包的,consumer不需要暴露服务
# scan:
# base-packages: com.example.dubbo_service.service #指定该项目模块启动的端口,不可与其他项目端口重复
server:
port: 8082

具体Controller消费者端

package com.example.dubbo_controller.controller;

import com.example.dubbo_interface.service.StuService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; @RestController
@RequestMapping("/stu")
public class StuController { /**
* 远程注入
* 从zookeeper注册中心获取该service的访问url
* 进行远程调用RPC
* 将结果封装成一个代理对象,给变量赋值
*/
//没timeout好像就出问题了??连不上??
//也可以在yml里边的consumer的timeout进行配置
@DubboReference/*(timeout = 5000)*/
StuService stuService; @RequestMapping("/login")
public String login(){
return stuService.login();
}
}

同上引入依赖

<!--依赖接口项目-->
<dependency>
<groupId>com.example</groupId>
<artifactId>dubbo_interface</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- Dubbo Spring Boot Starter -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.8</version>
</dependency>
<!--curator依赖-->
<!--Curator提供了一套Java类库, 可以更容易的使用ZooKeeper。 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>5.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>5.1.0</version>
</dependency>

启动类

package com.example.dubbo_controller;

import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; //开启基于Dubbo的注解
@EnableDubbo
@SpringBootApplication
public class DubboControllerApplication { public static void main(String[] args) {
SpringApplication.run(DubboControllerApplication.class, args);
}
}

公共接口

因为provider和consumer两个模块都会需要用到这个接口,所以不如抽取出来作为公共的接口

package com.example.dubbo_interface.service;

//公共接口
public interface StuService {
String login();
}

Dubbo-admin

人生建议: 直接用老版本的前后端未分离,直接可以一键启动使用,端口默认在本机的7001

关于老版本的dubbo-admin我是直接用的尚硅谷教程里边的的尚硅谷的文件里边应该会有,如果找不着的话也可以评论留言一下

修改application.properties

server.port

该项目要启动的端口

registry.address

要监测的注册中心的地址

启动之前要先启动zookeeper!!!(如何启动参照上边zookeeper安装)

访问localhost:端口号

默认用户名和密码都是root

最终效果

先开着zookeeper,如何启动service模块,再启动controller模块,最后启动dubbo-admin项目



可以看到有一个服务数,两个应用数,一个是提供者,一个是消费者

服务是我们的接口模块

提供者

消费者



​

访问我们的接口

完整工程代码

  • 这里三个模块的互相依赖关系pom文件,基于个人项目名称不同而有所不同,若对于pom文件和依赖关系还有点迷惑的小伙伴们欢迎评论区微信交流

写在最后

  • 分布式这一块还是刚刚入门,原理方面希望也能多了解了解,希望接下来还能继续坚持下去,多多补充这一块的知识。关于Dubbo的一些高级特性,以及zookeeper的具体学习,过段时间再来补充!(flag疯狂立起来了)

PPT来源

  • 黑马Dubbo教程
  • dubbo-admin文件来源: 尚硅谷

搭载Dubbo+Zookeeper踩了这么多坑,我终于决定写下这篇!的更多相关文章

  1. 搭建SpringBoot+dubbo+zookeeper+maven框架(一)

    这几天项目还没来,所以就自己试着参考网上的一些资料,搭建了一个SpringBoot+dubbo+zookeeper+maven框架,网上参考的很多资料照着他们一步一步搭建,最后很多都运行不通,很是郁闷 ...

  2. springboot+dubbo+zookeeper+mybatis

    参考地址:https://www.cnblogs.com/gaopengfirst/p/9555240.html 首先创建一个maven项目: 再在该父项目中创建3个module,分别是:provid ...

  3. (转)Dubbo + Zookeeper入门初探

    一.搭建java和tomcat环境 二.搭建zookeeper 三.搭建dubbo监控中心 四.配置项目 4.1 服务提供方代码 4.2 服务使用方代码 五.测试 2018年2月15日,阿里巴巴的du ...

  4. springboot整合dubbo+zookeeper最新详细

    引入 最近和小伙伴做一个比赛,处于开发阶段,因为涉及的服务比较多,且服务需要分开部署在不同的服务器上,讨论之后,打算采用分布式来做,之前学习springboot的时候,部分章节涉及到了springbo ...

  5. dubbo+zookeeper+springboot构建服务

    本次和大家分享的是dubbo框架应用的初略配置和zookeeper注册中心的使用:说到注册中心现在我使用过的只有两种:zookeeper和Eureka,zk我结合dubbo来使用,而Eureka结合s ...

  6. Android Camera开发经验总结以及踩过的那些坑

    写在开头 需求方:上传试卷的时候,用户自己拍的照片有很多问题.如:不清晰.图片歪了.错误图片等.我们要是能够对拍摄照片进行识别处理就好了,能够裁切矫正就更好了,最好可以像二维码扫描一样,直接识别处理- ...

  7. SpringBoot分布式:Dubbo+zookeeper

    西部开源-秦疆老师:SpringBoot + Dubbo + zookeeper 秦老师交流Q群号: 664386224 未授权禁止转载!编辑不易 , 转发请注明出处!防君子不防小人,共勉! 基础知识 ...

  8. Dubbo+Zookeeper(一)Zookeeper初识

    前面花了一段时间去学习SpringCloud的相关知识,主要是理解微服务的概念并使用SpringCloud的一系列组件实现微服务落地.学习这些组件本身是简单的,跟着操作一遍基本就会了,这也得益于Spr ...

  9. spring boot +dubbo+zookeeper

    dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案. 结合本公司的开发也是用的dubbo这款优秀的框架,加上 最近工作重心的.所以对于dubbo的 ...

随机推荐

  1. C#多线程开发-线程同步 02

    上一篇文章主要带领大家认识了线程,也了解到了线程的基本用法和状态,接下来就让我们一起学习下什么是线程同步. 线程中异常的处理 在线程中始终使用try/catch代码块是非常重要的,因为不可能在线程代码 ...

  2. IO流学习笔记(一)之FileWriter与FileReader

    IO流用来处理设备之间的数据传输 Java对数据的操作是通过流的方式 Java用于操作流的对象都在IO包中 流按照操作数据分为两种:字节流和字符流 流按流向分为:输入流和输出流 输入流和输出流是相对于 ...

  3. 【第二篇】- Maven 环境配置之Spring Cloud直播商城 b2b2c电子商务技术总结

    Maven 环境配置 Maven 是一个基于 Java 的工具,所以要做的第一件事情就是安装 JDK. 如果你还未安装 JDK,可以参考我们的 Java 开发环境配置. 系统要求 项目 要求 JDK ...

  4. springmvc配置过程中遇到的一些问题总结

    springmvc配置过程中遇到的一些问题总结 1.配置tomcat过程中的错误: 2.配置web.xml中DispatchServlet报红(配置好已有依赖条件下) 解决的办法: 因为新添加依赖,m ...

  5. tar解压缩问题

    gzip: stdin: unexpected end of filetar: 归档文件中异常的 EOFtar: 归档文件中异常的 EOFtar: Error is not recoverable: ...

  6. 理解MySQL回表

    回表就是先通过数据库索引扫描出数据所在的行,再通过行主键id取出索引中未提供的数据,即基于非主键索引的查询需要多扫描一棵索引树. 因此,可以通过索引先查询出id字段,再通过主键id字段,查询行中的字段 ...

  7. PTA 面向对象程序设计 6-2 逆序字符串

    6-2 逆序字符串 设计一个void类型的函数reverse_string,其功能是将一个给定的字符串逆序.例如,给定字符串为"hello",逆序后为"olleh&quo ...

  8. java循环结构、数组

    数组 数组是是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理. 数组本身是引用数据类型,既可以存储基本数据类型,也可以存储引用数据类型.它的元素相当于 ...

  9. PHP方法的返回值

    不仅是PHP,大部分编程语言的函数或者叫方法,都可以用return来定义方法的返回值.从函数这个叫法来看,本身它就是一个计算操作,因此,计算总会有个结果,如果你在方法体中处理了结果,比如进行了持久化保 ...

  10. php安装imagick扩展

    下面/usr/local/php5是php的安装目录 安装imagickcd /usr/local/srcwget http://pecl.php.net/get/imagick-3.0.1.tgz  ...