dubbo(四)
阅读原文时间:2023年07月09日阅读:1

前言

首先,要了解dubbo,就得了解,它是在什么背景下产生的?这就需要从架构的发展说起。

孟老师从事软件开发2008年份,那时候我上高一,那个时候,淘宝、京东都还没有火起来。那个时候的软件都很简单,应用的访问量都很小,只需要一个单一的应用,就可以满足所有的需求:例如我做的

zbj系统,一共就不到五个人会用,此时,影响响应效率的,主要是与数据库的交互。

但是,谈到业务系统,尤其是zb业务系统,全国有很多的分公司,这个时候,用户的访问量就上来了,会有上百,上千的访问量,这样,单一应用增加机器带来的加速度越来越小,所以需要将应用拆成互

不相干的几个应用,以提升效率。这就是垂直应用架构(这里我要重点说明的,垂直应用之间,是独立的应用,网上比较流行的关于架构发展的说明,我对此的理解有点不同,下面详谈)。例如zb系统就有很多的周边系统。 注意:当拆分的垂直应用越来越多时,不同的系统间也是需要进行交互的,因为这多个系统本来就是为了便于开发人员维护,提高访问效率,而拆分成多个系统的,之间肯定会有交互的,这个从rbz的各系统间的交互就可以看出来。而每个季度,不同系统之间的数据一致性、数据同步,真的是一件让人头痛的事情,为此还专门开发了数据仓库系统,用于核对数据的一致性,至于以后的理想--所有的数据皆取自于此,我就不知道能不能实现了,毕竟我已经走了。更甚于,随着业务的增加,子系统必然会越来越多,系统间的交互更是如此,不难想象,运维、数据等问题将会导致整个项目的维护成本越来越高。幸而现在有了微服务了,这个是后话,在没有微服务时,垂直应用的后续发展是分布式服务框架。这是我今天要重点整理的。

随着互联网的发展,访问量激增,业务庞杂而繁多,网站应用规模不断扩大,常规的垂直应用架构已无法应对,分布式架构以及流动计算架构势在必行。垂直架构也无法满足开发成本、用户访问等,分布式、集群、微服务应运而生。但是,这所有的技术,都是为了适应功能的需要。到底是功能附着于技术,还是技术附着于需求,这个问题,还是看你想换工作,还是在做需求吧,哈哈。

由此,也可以看出来,IT这个行业,是需要不断学习,加班,充实自己的。划重点:加班!

网上比较多的说法:

  • 单一应用架构:当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。 此时,用于简化增删改查工作量的 数据访问框架(ORM) 是关键。(常见的框架:hibernate、mabatis)

  • 垂直应用架构:当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率。  此时,用于加速前端页面开发的Web框架(MVC) 是关键。(我对这句话很有看法,不明白为什么非要冷不丁的提这么一嘴。既然是将单一应用拆分成多个独立的应用,那么跟这个MVC有个屁关系?我的理解是:MVC是针对于单独的一个应用来说的,是一种开发模型,一种开发习惯。每个单独的应用,都可以采用这种开发方式,同样,也可以不采用这种开发方式。如果我拆分出来的子系统(垂直应用),就是不采用这个Web框架(MVC) ,你还怎么给我关键?)所以,我认为,提高效率是提高效率,MVC是MVC,是两种概念。你可以说采用MVC框架来开发的项目,提高它采用的框架的效率,质量,是提高这个项目效率的关键;但是不能说用于加速前端页面开发的Web框架(MVC) 是提高垂直应用架构效率的关键。要我来理解,倒不如看你拆的项目有多细、集群布的有多少、服务器有多少来的关键,既然是垂直应用,就是说拆分成了N个独立项目了,那不就是N个单一应用么?要非说关系,可能在这个阶段,采用MVC框架来开发项目是首选吧。

        mvc垂直架构逻辑架构图:《分布式服务框架:原理与实践》--李林峰

  • 分布式服务架构:当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。 
    此时,用于提高业务复用及整合的分布式服务框架(RPC-Remote Procedure Call Protocol——远程过程调用协议,即分布式,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。) 是关键。
  • 流动计算架构 :当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。

此时,用于提高机器利用率的资源调度和治理中心(SOA-Service-Oriented Architecture,即面向服务架构。它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。) 是关键。

1、单体应用架构(ORM)

单体架构特点:

(1)所有的功能集成在一个项目工程中,功能模块耦合度太高了。

(2)所有的功能打一个war包部署到Docker或服务器

(3)应用与数据库分开部署

(4)通过部署应用集群和数据库集群来提高系统的性能

(5)部署时间那不是一般的长

单体架构优点:项目架构简单,前期开发成本低,周期短,小型项目的首选。

单体架构缺点:

(1)全部功能集成在一个工程中,对于大型项目不易开发、扩展及维护

(2)系统性能扩展只能通过扩展集群结点,成本高、有瓶颈

(3)技术栈受限

2、垂直应用架构(Modle View Controller,简称MVC)当业务规模很小时,将所有功能都部署在同一个进程中,通过双机或者前置负载均衡器实现负载分流;此时,用于分离前后台逻辑的 MVC 架构是关键。(难道垂直应用架构里的垂直指的就是MVC这种垂直分层的开发模式?而垂直应用架构就是指将一个大的项目拆分成N个采用MVC框架开发的子应用?拆分的极限就是当业务规模很小时,不用拆,那么就是单一项目----1?那可不用于分离前后台逻辑的 MVC 架构是关键。)

垂直架构特点:

(1)以单体结构规模的项目为单位进行垂直划分项目即将一个大项目拆分成一个一个单体结构项目。

(2)项目与项目之间的存在数据冗余,耦合性较大,比如上图中三个项目都存在客户信息。

(3)项目之间的接口多为数据同步功能,如:数据库之间的数据库,通过网络接口进行数据库同步。

垂直架构优点:

(1)项目架构简单,前期开发成本低,周期短,小型项目的首选。

(2)通过垂直拆分,原来的单体项目不至于无限扩大。(3)不同的项目可采用不同的技术。

垂直架构缺点:

(1)系统性能扩展只能通过扩展集群结点,成本高、有瓶颈。

3、面向服务架构(Service Oriented Architecture,简称SOA)

当垂直应用越来越多,应用之间交互不可避免,将核心和公共业务抽取出来,作为独立的服务,实现前后台逻辑分离。此时,用于提高业务复用及拆分是关键,服务数量也会越来越多,服务生命周期管控和运行态的治理成为瓶颈,此时用于提升服务质量的 SOA 服务治理是关键。

(1)企业服务总线(Enterprise Service Bus,简称ESB)ESB概念是从面向服务体系架构(Service Oriented Architecture, SOA)发展而来的。SOA描述了一种IT基础设施的应用集成模型;其中的软构件集是以一种定义清晰的层次化结构相互耦合。一个ESB是一个预先组装的SOA实现,它包含了实现SOA分层目标所必需的基础功能部件。在企业计算领域,企业服务总线是指由中间件基础设施产品技术实现的、 通过事件驱动和基于XML消息引擎,为更复杂的面向服务的架构提供的软件架构的构造物。企业服务总线通常在企业消息系统上提供一个抽象层,使得集成架构师能够不用编码而是利用消息的价值完成集成工作。企业服务总线提供可靠消息传输,服务接入,协议转换,数据格式转换,基于内容的路由等功能,屏蔽了服务的物理位置,协议和数据格式。ESB是将所有的系统的交互都放在SOA统一服务总线上面来控制处理,技术人员可以开发符合ESB标准的组件(适配器)将外部应用连接至服务总线。
(2)WebService的常用的方法

A、远程过程调用协议(Remote Procedure Call,简称RPC),面向方法RPC是一种允许分布式应用程序调用网络上不同计算机的可用服务的机制。比如从一台机器(客户端)上通过参数传递的方式调用另一台机器(服务器)上的一个函数或方法(可以统称为服务)并得到返回的结果。
下面简单介绍几种典型的RPC远程调用框架:

(a)RMI实现,利用java.rmi包实现,基于Java远程方法协议(Java Remote Method Protocol)和java的原生序列化

(b)Hessian,是一个轻量级的remoting onhttp工具,使用简单的方法提供了RMI的功能。基于HTTP协议,采用二进制编解码

(c)thrift是一种可伸缩的跨语言服务的软件框架。thrift允许你定义一个描述文件,描述数据类型和服务接口。依据该文件,编译器方便地生成RPC客户端和服务器通信代码

(d)dubbo,阿里的RPC框架

(e)还有SpringCloud框架,微服务全家桶。为开发人员提供了快速构建分布式系统的一些工具,包括配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等

B、简单对象访问协议(Simple Object Access Protocol,简称SOAP),面向消息
简单对象访问协议是一种数据交换协议规范,是一种轻量的、简单的、基于XML的协议的规范。SOAP协议和HTTP协议一样,都是底层的通信协议,只是请求包的格式不同而已,SOAP包是XML格式的。SOAP的消息是基于xml并封装成了符合http协议,因此,它符合任何路由器、 防火墙或代理服务器的要求。

C、表象化状态转变(Representational State Transfer,简称REST),面向资源
采用Web 服务使用标准的 HTTP 方法 (GET/PUT/POST/DELETE) 将所有 Web 系统的服务抽象为资源,REST从资源的角度来观察整个网络,分布在各处的资源由URI确定,而客户端的应用通过URI来获取资源的表征。RESTful是一种架构设计风格,提供了设计原则和约束条件,而不是架构,而满足这些约束条件和原则的应用程序或设计就是 Restful架构或服务。RESTful的核心就是后端将资源发布为URI,前端通过URI访问资源,并通过HTTP动词表示要对资源进行的操作。
D、REST、SOAP和RPC之间的区别

(a)在SOAP模式把HTTP作为一种通信协议,而不是应用协议。所以http中的表头,错误信息等全部无视。实际上http有 put get post delete等方法;REST 则不然,HTTP method中的 POST GET PUT DELETE 都是与请求方法对应的,rest真正实现了http的五层结构

(b)REST是一种轻量级的Web Service架构风格,其实现和操作比SOAP和RPC更为简洁

(c)SOAP可以使用任何语言来完成,只要发送正确的soap请求即可,基于soap的服务可以在任何平台无需修改即可正常使用
(d)RPC 风格的 Web Service 跨语言性不佳
(e)总结建议成熟度上:SOAP在成熟度上优于REST;效率和易用性上:REST更胜一筹;安全性上:SOAP安全性高于REST,因为REST更关注的是效率和性能问题;总体上,因为REST模式的Web服务与复杂的SOAP和XML-RPC对比来讲明显的更加简洁,越来越多的Web服务开始采用REST风格设计和实现。

面向服务架构特点:

(1)基于SOA的架构思想将重复、公用的功能抽取为组件,以服务的方式给各个系统提供服务。

(2)各个项目(系统)与服务之间采用webservice、rpc等方式进行通信。

(3)ESB企业服务总线作为项目与服务之间通信的桥梁。

面向服务架构优点:

(1)将重复的功能抽取为服务,提高开发效率,提高系统的可重用性、可维护性。

(2)可以针对不同服务的特点制定集群及优化方案。

(3)采用ESB减少系统中的接口耦合。

面向服务架构缺点:

(1)系统与服务的界限模糊,不利于开发及维护。

(2)虽然使用了ESB,但是服务的接口协议不固定,种类繁多,不利于系统维护。

(3)抽取的服务的粒度过大,系统与服务之间耦合性高。

4、微服务架构(MSA)

随着敏捷开发、持续支付、DevOps 理论的发展和实践,以及基于 Docker 等轻量级容器 (LXC) 部署应用和服务的成熟,微服务架构开始流行,逐渐成为应用架构的未来演进方向。通过服务的原子化拆分,以及微服务的独立打包、部署和升级,小团队敏捷交付,应用的交付周期将缩短,运营成本也将大幅下降。微服务在本质上,就是RPC。RPC有基于TCP的、HTTP的,MQ的等等。spring cloud是基于spring boot的,spring boot 实现的是http协议的RPC,算是RPC的一个子集。

微服务架构特点:

(1)将系统服务层完全独立出来,并将服务层抽取为一个一个的微服务。

(2)微服务遵循单一原则。(3)微服务之间采用RESTful等轻量协议传输。

微服务架构优点:

(1)服务拆分粒度更细,有利于资源重复利用,提高开发效率。

(2)可以更加精准的制定每个服务的优化方案,提高系统可维护性。

(3)微服务架构采用去中心化思想,服务之间采用RESTful等轻量协议通信,相比ESB更轻量。

(4)适用于互联网时代,产品迭代周期更短。

微服务架构缺点:

(1)微服务过多,服务治理成本高,不利于系统维护。

(2)分布式系统开发的技术成本高(容错、分布式事务等),对团队挑战大。到此,软件系统应用架构介绍完了,希望能帮大家更深刻认识其中的应用架构思想,以便日后软件架构设计和应用Docker化更加合理。

参看链接:http://www.360doc.com/showweb/0/0/962416508.aspx

针对与单体、垂直进行了详细分析。针对第三点中的RPC、分布式的理解,这两个是有连贯性的,其实,可以这么理解,在rbz的业务系统与周边子项目中,系统之间存在交互,调用;但是,因为只是通过HTTPclient、socket等方式互相调用,并没有用到RPC-分布式框架,只能称之为垂直应用架构。当垂直服务越来越多,调用越来越多,为了便于管理,RPC-分布式服务架构应用而生。本文要介绍的dubbo就是一个RPC框架,如下图:

dubbo工作原理图简单说明

下面会进行详细的说明,从简单使用,到ego项目的实战。这里主要简单提下dubbo的发布服务的原理:就是编写一个项目,里面需要配置zookeeper的地址,发布到注册中心(注册中心就是zookeeper),这个项目就是服务的提供者-provider;然后消费者通过配置zookeeper的地址,去注册中心拿到服务地址,去调动服务者,来实现功能。下面再具体谈。

;至于后面的SOA-Service-Oriented Architecture,即面向服务架构。它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。其实就是根据常用的具体功能,将功能抽象为服务,发布到注册中心。

  • 面向服务架构。
  • 是一种软件设计模式,主要应用于不同应用组件之间通过某种协议来互操作。
  • 因为SOA不依赖于任何技术,因此SOAP、RPC、REST是对SOA的不同实现。

5.1、SOA

英文名称:Service Oriented Ambiguity

中文名称:面向服务架构

SOA是一种思想,目的是提供一种设计项目的思路,让开发时更有效率。

例如原来的分布式项目中,在每个项目都要访问数据库,这样就造成了代码的冗余:

使用SOA架构后:

  • 专门访问数据库服务(项目)
  • 开发时可以实现数据访问控制和代码复用

实现 SOA 架构时,常用服务:

  • Dubbo作为服务;

  • WebService作为服务;

  • Dubbox作为服务;

  • 服务方就是web项目,调用 web 项目的控制器;

    • 使用 HttpClient 可以调用其他项目的控制器。

5.2 RPC

英文名称:Remote Procedure Call Protocol

中文名称:远程过程调用协议

解释:客户端(A)通过互联网调用远程服务器,不知道远程服务器的具体实现,只知道远程服务器提供了什么功能。

SOA

  • 面向服务架构。
  • 是一种软件设计模式,主要应用于不同应用组件之间通过某种协议来互操作。
  • 因为SOA不依赖于任何技术,因此SOAP、RPC、REST是对SOA的不同实现。

SOAP

  • 简单对象访问协议,是一种轻量的、简单的、基于XML的协议
  • 可在任何传输协议(诸如 TCP、HTTP、SMTP,甚至是 MSMQ)上使用
  • 其中,SOAP广泛使用的是基于HTTP和xml协议的实现(SOAP=RPC+HTTP+XML),也就是大家常提的Web Service使用的通信协议

REST

  • 表征状态转移。采用Web 服务使用标准的 HTTP 方法 (GET/PUT/POST/DELETE) 将所有 Web 系统的服务抽象为资源。
  • 目前较为流行的一种组件通信方式。在微服务中有较多使用
  • REST不是一种协议,它是一种架构, 一种 Web Service 能够如果满足 REST 的几个条件, 通常就称这个系统是 Restful的

RPC

  • 远程方法调用,就是像调用本地方法一样调用远程方法
  • dubbo就是一种RPC框架。他的通讯协议是RPC协议
  • 4种典型RPC远程调用框架:RMI、Hessian、thrift、dubbo
  • Spring Cloud也是一种RPC框架,但是区别是它使用的是http协议(要区分应用层协议和传输协议)的传输,整体技术和普通RPC如dubbo[使用TCP协议]/thrift有很大区别

微服务和SOA的区别

  • 微服务是SOA架构演进的结果。
  • 两者说到底都是对外提供接口的一种架构设计方式,随着互联网的发展,复杂的平台、业务的出现,导致SOA架构向更细粒度、更通过化程度发展,就成了所谓的微服务了。
  • 两者说到底都是对外提供接口的一种架构设计方式,随着互联网的发展,复杂的平台、业务的出现,导致SOA架构向更细粒度、更通过化程度发展,就成了所谓的微服务了。
  • 微服务是SOA发展出来的产物,它是一种比较现代化的细粒度的SOA实现方式。
  • SOA与微服务的区别在于如下几个方面:
    - 微服务相比于SOA更加精细,微服务更多的以独立的进程的方式存在,互相之间并无影响
    - 微服务提供的接口方式更加通用化,例如HTTP RESTful方式,各种终端都可以调用,无关语言、平台限制
    - 微服务更倾向于分布式去中心化的部署方式,在互联网业务场景下更适合

RPC与 REST 的区别

  • Rest基于http作为应用协议,不同语言之间调用比较方便。典型代表就是spring cloud框架
  • RPC是基于TCP和HTTP协议的,是把http作为一种传输协议,本身还会封装一层RPC框架的应用层协议,不同语言之间调用需要依赖RPC协议,典型代表就是Dubbo

REST和SOAP协议的区别

  • REST基于HTTP协议
  • SOAP基于任何传输协议:诸如 TCP、HTTP、SMTP,甚至是 MSMQ等
  • SOAP 是一种 RPC 框架,HTTP 是承载协议,本身是一种应用协议,实现了调用远程就像调用本地接口一样
  • REST 是一种架构风格,客户端需要通过 URL 去调用服务端,HTTP 本身即是承载协议,也是应用协议
  • SOAP 适合企业应用,REST 更适合高并发场景。 SOAP 的业务状态大多是维护在服务端的,而 REST 是无状态的操作,维护的是资源状态,将会话状态交由客户端维护

参考链接:

https://www.cnblogs.com/myitnews/p/11479438.html

https://blog.csdn.net/dglsx123/article/details/100936645

一件事情,拆分开,多个人来做。(现实举例:盖房拆分为地基、主体、装修三步,不同的人负责不同的模块)。这样来提高效率。

多个人,做的都是同一件事情。(现实举例:多个人,一起来做盖房这一件事情(此时盖房是一个事件)。若跟上面的例子联系起来,其实就是地基这件事,多个人来做,这是一个集群。地基、主体、装修可以分成三个集群)。

一、什么是double

Dubbo是一个分布式服务框架,致力于提高性能和透明化的RPC远程服务调用方案,是阿里巴巴SOA服务化治理方案的核心框架。Dubbo现在已经停止更新了。Dubbox产生。

http://dubbo.io/

随着互联网的发展,网站应用规模不断扩大,常规的垂直应用架构已无法应对,分布式架构以及流动计算架构势在必行。

4.1架构图

记住dubbo的工作流程及原理,重点就是记住这张图。

现实例子:

4.2 工作流程

  • dubbo的注册中心多采用zookeeper。关于zookeeper的介绍详见链接:https://www.cnblogs.com/zhangshuaivole/p/14409420.html
  • dubbo只是一个分布式的框架,它的注册中心还是需要依托于其他的组件;
  • dubbo的运行也是在spring的容器上;
  • 安装并启动zookeeper,如果不是在本地,需要关闭防火墙;
  • 创建provider提供服务【服务可以理解为方法】;
  • 将服务通过配置文件中配置zookeeper的地址,发布到zookeeper;
  • 创建Consumer项目,调用服务接口;
  • Dubbo-监控中心监控已发布的服务;
  • Dubbo-provider提供者打包以及运行:这里打包并发布的是服务提供者项目。将服务提供者发布到注册中心,消费者想怎么调怎么调,这个在ego项目里体现的更直观。

  • 注册中心(Registry)是整个Dubbo架构重要部分,是Provider和Consumer桥梁。
  • 注册中心,应该在spring 配置文件中配置!
  • Multicast注册中心:不常用。

不需要启动任何中心节点,只要广播地址一样,就可以互相发现

如果一个机器上同时启了多个消费者进程,消费者需声明unicast=false,否则只会有一个消费者能收到消息

  • Zookeeper注册中心:工作中推荐使用!

建议使用dubbo-2.3.3以上版本的zookeeper注册中心客户端。
Zookeeper是Apacahe Hadoop的子项目,是一个树型的目录服务,支持变更推送,适合作为Dubbo服务的注册中心,工业强度较高,
可用于生产环境,并推荐使用,参见:http://zookeeper.apache.org

  • Redis注册中心:

Redis是一个高效的KV存储服务器

Simple注册中心


此SimpleRegistryService只是简单实现,不支持集群,可作为自定义注册中心的参考,但不适合直接用于生产环境。

  • 在这里只是通过代码,演示下:
  • dubbo如何创建服务;
  • dubbo如何将服务发布到注册中心;
  • 消费者如何通过注册中心调用服务;
  • dubbo检测中心如何监控dubbo服务;
  • 打包dubbo服务;
  • 实际中如何通过dubbo构建分布式项目,在下面的电商-ego项目来说明。

这里创建的项目是在eclipse里创建的。

7.1 启动注册中心

上传并解压zookeeper到Linux,启动zookeeper,关闭防火墙。

说白了,dubbo就是用的zookeeper的数据发布及订阅的功能。

7.2创建provider提供服务【服务可以理解为方法】。

1. 创建一个maven项目,packing选择jar。
2. 配置pom.xml
a) 添加一个dubbo相关的jar,自动会添加spring jar包,但是,spring版本2.5.6,我们通常使用的是4.1.6.把自动加载的jar 去除。
b) 添加一个zookeeper相关的jar
c) 添加一个spring相关的jar

pom.xml文件:

http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
com.bjsxt
cdubbo-p
0.0.1-SNAPSHOT


com.alibaba dubbo 2.5.3 org.springframework spring org.springframework spring-context 4.1.6.RELEASE com.101tec zkclient 0.10


maven-assembly-plugin assembly/assembly.xml make-assembly package single

3.新建接口DemoService和实现类DemoServiceImpl和实体类Student类

3.1实体类需要实现Serializable接口

3.2实现类上的@Service是dubbo的注解,不要导错包

代码:

pojo:

package com.bjsxt.pojo;

import java.io.Serializable;

/**
* @ClassName:Student
* @Description: 学生类,应该被序列化,
*/

public class Student implements Serializable {

// 定义属性  
private int id;  
private String name;  
public int getId() {  
    return id;  
}  
public void setId(int id) {  
    this.id = id;  
}  
public String getName() {  
    return name;  
}  
public void setName(String name) {  
    this.name = name;  
}  
@Override  
public String toString() {  
    return "Student \[id=" + id + ", name=" + name + "\]";  
}  
public Student() {  
    super();  
    // TODO Auto-generated constructor stub  
}  
public Student(int id, String name) {  
    super();  
    this.id = id;  
    this.name = name;  
}

}

接口:

package com.bjsxt.service;

import java.util.List;

import com.bjsxt.pojo.Student;

/**
* @ClassName:DemoService
* @Description:
*/

public interface DemoService {

// 查找所有学生信息的方法  
List<Student> findAll();  

}

实现类:

package com.bjsxt.service.impl;

import java.util.ArrayList;
import java.util.List;

import com.alibaba.dubbo.config.annotation.Service;
import com.bjsxt.pojo.Student;
import com.bjsxt.service.DemoService;

@Service
public class DemoServiceImpl implements DemoService {

/\*\*  
 \* 定义服务  
 \*/  
@Override  
public List<Student> findAll() {  
    // 从数据库中取得数据。 使用list、集合来模拟数据库中的数据  
    List<Student> list = new ArrayList<>();  
    list.add(new Student(1, "马蓉"));  
    list.add(new Student(2, "宝宝不哭"));  
    list.add(new Student(3, "宋哲"));  
    return list;  
}  

}

4.新建spring配置文件【spring-dubbo.xml】;建立在src/main/sources/META-INF/spring/*.xmlSpring 。配置文件要做的是,暴露服务,指定到注册中心的地址等。这里的目录结构是阿里推荐的。


http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

如上所示,通过在spring-dubbo.xml配置文件中的标签dubbo:registry,将服务注册到注册中心。

这里暴露接口有两种方式:使用注解和使用配置方式。

5、启动Dubbo的Provider,创建测试类

package com.bjsxt.test;

import com.alibaba.dubbo.container.Main;

/**
* @ClassName:TestDubbo
* @Description:
*/

public class TestDubbo {
public static void main(String[] args) {
// 启动dubbo 调用dubbo中的Main方法!
Main.main(args);
}
}

注意:启动dubbo前,必须保证zookeeper启动成功,并可以调通(是否关闭防火墙)。

6、服务者项目目录结构

7.3创建Consumer项目,调用服务接口

1.新建Maven Project 项目,命名为dubbo-c,packing依然选择jar

2.配置pom.xml和dubbo-p的pom.xml中的pom.xml一样。

3.把dubbo-p的pojo,service包全部拷贝过来即可。

4.编写consumer中的service 接口和实现类。

代码:

服务者接口:

package com.bjsxt.service;

import java.util.List;

import com.bjsxt.pojo.Student;

/**
* @ClassName:DemoService
* @Description: 服务提供者接口
*/

public interface DemoService {
// 查找所有学生信息的方法
List findAll();
}

服务消费者接口:

package com.bjsxt.consumer.service;

import java.util.List;

import com.bjsxt.pojo.Student;

/**
* @ClassName:DemoConsumerService
* @Description: 定义服务消费者接口
*/

public interface DemoConsumerService {

/\*\*  
 \*  
 \* @Description: 服务消费者方法  
 \* @return  
 \* @author mengqx  
 \* @date   2017年11月20日  
 \*/  
List<Student> selAll();  

}

消费者接口实现类:

package com.bjsxt.consumer.service.impl;

import java.util.List;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.alibaba.dubbo.config.annotation.Reference;
import com.bjsxt.consumer.service.DemoConsumerService;
import com.bjsxt.pojo.Student;
import com.bjsxt.service.DemoService;

/**
* @ClassName:DemoConsumerServiceImpl
* @Description: 实现消费者接口
*/

public class DemoConsumerServiceImpl implements DemoConsumerService{

/\*\*  
 \* 在服务消费者实现的时候,去调用服务提供者的接口!  
 \* 需要一个注解  
 \*/  
@Reference  
private DemoService demoService;

@Override  
public List<Student> selAll() {  
    //    通过@Reference注解来取得服务提供者的方法。  
    return demoService.findAll();  
}

public static void main(String\[\] args) {  
    // 读取spring 配置文件,取得bean  
    ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("spring-dubbo.xml");  
    DemoConsumerService service = ac.getBean("demoConsumerService",DemoConsumerService.class);  
    List<Student> selAll = service.selAll();  
    // 循环遍历数据,数据实际来源应该是服务提供者!  
    for (Student student : selAll) {  
        System.out.println(student);  
    }  
}

}

可以看出,是通过注解@Reference来调用服务提供者的接口的实现。

5、配置文件


http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

在这里配置注册中心地址,并配置对@References注解的支持。

6、运行测试结果

7、消费者项目目录结构

7.4Dubbo-监控中心

1.      把dubbo-admin-2.5.3.war粘贴到tomcat/webapps中,启动tomcat,dubbo-admin-2.5.3.war在资料03里面。

2.      修改dubbo-admin-2.5.3/WEB-INF/dubbo.properties

a)       vim dubbo.properties

dubbo.registry.address=zookeeper://192.168.26.30:2181

dubbo.admin.root.password=root

dubbo.admin.guest.password=guest

3.      启动tomcat,访问dubbo-admin-2.5.3.可以直观看见图形界面。

7.5Dubbo-provider提供者打包以及运行

1.            Maven中的Assembly 插件就可以把Maven项目打包.

2.            实现步骤:在原有项目基础上添加下面步骤(只需要修改Provider的项目,打包只涉及Provider的打包)

3.            在Provider的Maven项目的pom.xml中添加assembly插件

maven-assembly-plugin assembly/assembly.xml make-assembly package single

maven-assembly-plugin

assembly/assembly.xml

make-assembly

package

single

5.在项目根目录下新建assembly文件夹

6.  解压01资料/04 assembly压缩包,并把bin和conf文件夹复制进来.放到assembly文件夹中.

7.  粘贴后要把conf/dubbo.properties中内容清空,因为所有信息已经在  Spring配置文件中配置过.

8.  在assembly文件夹下新建assembly.xml文件,并粘贴下面内容


http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd"> assembly tar.gz true assembly/bin bin 0755 assembly/conf conf 0644 lib

最后 :右键项目--> Run as --> Maven Install 后会在target下生成.tar.gz的文件

Dubbo-provider 项目在linux 系统上运行

1.      导入到linux 系统中 /root根目录下

2.     

3.      解压文件

a)       tar -zxvf du-provider-0.0.1-SNAPSHOT-assembly.tar.gz

4.      进入到bin中

a)       cd bin

5.      运行./start.sh 即可

6.      运行项目的消费者

7.

需要注意的是:上述打包过程会用即可。主要还是体会分布式项目的搭建流程,工作原理。到这里为止,关于分布式框架-dubbo的介绍、工作流程、原理、搭建、发布、消费、打包、监控都梳理完成。从打包这里也可以看出来,我们最终需要打包发布的服务就是服务提供者,将服务提供者发布到zookeeper上,至于什么时候,由谁来调用,那就是服务消费者的事了。这个在下面的电商项目中体现的比较直观。

其实服务的消费者也是需要打包发布的。这是一个整体的项目。如下图是ego项目的SOA架构图:抽象出来,其实dubbo就是服务的提供者,发布在zookeeper上,一切与数据库的交互都有服务提供者去完成(这样不就避免了在垂直应用架构那里各个应用之间的数据同步问题了。)。而上面的不同的模块,都是根据常用的具体功能抽取出来的模块,他们都是服务的消费者(是单独的一个又一个应用,端口号都不一样),可以部署在不同的服务器上,根据需要,从zookeeper上订阅服务,并调用服务提供者。其实不同的消费者之间也可以通信,不过那就是跨域访问了,可以用jsonp、socket、httpclient等方式。

这里不再赘述项目搭建的具体流程,已将搭建的流程视频看了一遍了。具体操作起来很简单。

  • 这里只是通过这个分布式电商项目,来理解分布式项目。ego项目架构的理解;

  • 整体环境的搭建思路:创建父项目、创建服务提供者模块项目、创建实体类模块项目、创建公共类模块项目、创建服务消费者。如下:

    • Ego-parent :父项目---pom 这是父项目,pom文件;里面会定义项目需要的依赖版本等。
      Ego-pojo:子项目---jar 实体类,需要序列化,因为provider与consumer之间是网络通信,不序列化会报错。
      Ego-common:子项目---jar 公共类项目,pom文件中添加需要添加对Ego-pojo的依赖。
      Ego-service:子项目---jar 只是接口,pom文件中添加需要添加对Ego-common的依赖。
      Ego-dubbo:子项目---jar 是对Ego-service对的实现,需要添加对Ego-service的依赖。这个子项目是服务的提供者。这里与上面对dubbo应用的区别是,将服务提供者的接口与实现分成了两个子项目。在打包时,只需要打这个子项目的包就行了。
      Ego-manager:子项目---war 8080--(在pom文件中配置) 这个是后台管理的子项目,是服务消费者。pom文件中添加需要添加对Ego-service的依赖。 这里不依赖dubbo,依赖dubbo直接就可以调用服务提供者的实现类了。依赖Ego-service的话,跟上面对dubbo应用的区别是不用在在消费者项目里写一个服务提供者的接口了,有依赖了,直接导入接口,就可以通过注解@Reference调用发布到注册中心的Ego-dubbo的服务。

      --以后随着业务的扩充,还会有更多的消费者,他们有不同的端口号,是一个个独立的应用,如:
      ego-item---存储商品信息 8081--将商品的详细信息存储到redis
      ego-portal--- 前台页面 8082
      ego-seach---搜索商品-solr 8083--搭建solr将商品信息存储到solr中
      ego-passport---单点登录 8084
      ego-cart----购物车 8085--存储在redis中,购物车的信息
      ego-oder---订单 8086
      ego-pay---直接写到ego-oder中

      上述不同的模块,有前台页面的,再创建父类的module模块时,需要选择为war类型,没有前台页面的创建为jar类型即可。

      jar包无需部署直接可以调用,war包需要部署,依赖tomcat。

  • 项目是如何构建:通过maven构建,使用Maven构建工具,这个项目是用eclipse进行开发的。

  • 服务提供者是如何实现对服务的提供:见第二点中的分析。下面提供配置文件摘记。

  • 消费者是如何调用服务的:见第二点中的分析。下面提供配置文件摘记。

  • 发布服务到注册中心;

  • 部署消费者到Linux;

  • 写到这里,也可以看出来,越往后,难点往往是比较复杂的项目的配置,不再是码代码。

  • 梳理几个比较常出现的技术点:nginx、vsftp、单点登录、redis。

  • 电商项目,token==》redis 使用token;乐观锁中的watch

8.1 系统架构

8.2 项目基于SOA的架构

通过ego项目来理解分布式项目:

通过搭建ego项目;并对ego项目的架构理解,不难看出,分布式项目,就是将常用的功能实现,抽象成了一个又一个的服务,通过RPC框架(这里是dubbo)来管理,一切与数据库的交互都放在了服务提供者里(这里的服务提供者provider就是dubbo),实现服务后,将服务注册到注册中心,这里的注册中心是zookeeper。这样,就将庞杂而繁复的一个巨大的项目,拆分成了一个又一个的服务,发布到了一个管理服务的注册中心(不难想象,这对于项目的后期维护提供了多么大的便利,又多么大程度的降低了功能的耦合)。OK,现在服务提供好了,实现有了,剩下想要怎么用就是消费者的事了。上图的portal、search、manager···都是消费者,他们是开发人员(需求人员、业务人员?)根据不同的功能,拆分出来的N个应用。这样,就完美的将项目拆分了。需要什么功能,就去调对应的服务。这样,也可以有针对性的根据不同模块的访问量来提供负载。

8.3 ego-parent

pom.xml文件

http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
com.ego
ego1-parent
0.0.1-SNAPSHOT
pom


3.0.1 2.2 1.2 4.1.6.RELEASE 3.2.7 1.2.3 1.2.17 5.1.38 2.4.1 1.3.1 2.2 1.8.6 2.2 2.5.3 0.10 2.8.1 3.3 4.1.6




javax.servlet javax.servlet-api ${javax.servlet-api-version} provided

javax.servlet.jsp jsp-api ${jsp-api-version} provided

jstl jstl ${jstl-version}

org.springframework spring-webmvc ${spring-version}
org.springframework spring-jdbc ${spring-version}

org.mybatis mybatis ${mybatis-version}

org.mybatis mybatis-spring ${mybatis-spring-version}

log4j log4j ${log4j-version}

mysql mysql-connector-java ${mysql-connector-java-version}

com.fasterxml.jackson.core jackson-databind ${jackson-version}

commons-fileupload commons-fileupload ${commons-fileupload}
commons-io commons-io ${commons-io-version}
org.aspectj aspectjweaver ${aspectjweaver-version}

        <dependency>  
            <groupId>com.alibaba</groupId>  
            <artifactId>dubbo</artifactId>  
            <version>${dubbo-version}</version>  
            <exclusions>  
                <exclusion>  
                    <artifactId>spring</artifactId>  
                    <groupId>org.springframework</groupId>  
                </exclusion>  
            </exclusions>  
        </dependency>  
        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-context</artifactId>  
            <version>${spring-version}</version>  
        </dependency>  
        <dependency>  
            <groupId>com.101tec</groupId>  
            <artifactId>zkclient</artifactId>  
            <version>${zkclient-version}</version>  
        </dependency>  
        <dependency>  
            <groupId>com.github.pagehelper</groupId>  
            <artifactId>pagehelper</artifactId>  
            <version>${pagehelper-version}</version>  
        </dependency>  
        <!-- ftpclient -->  
        <dependency>  
            <groupId>commons-net</groupId>  
            <artifactId>commons-net</artifactId>  
            <version>${ftpclient-version}</version>  
        </dependency>  
        <!-- jedis -->  
        <dependency>  
            <groupId>redis.clients</groupId>  
            <artifactId>jedis</artifactId>  
            <version>${jedis-version}</version>  
        </dependency>  
    </dependencies>  
</dependencyManagement>  
<build>  
    <resources>  
        <resource>  
            <directory>src/main/java</directory>  
            <includes>  
                <include>\*\*/\*.properties</include>  
                <include>\*\*/\*.xml</include>  
            </includes>  
            <filtering>false</filtering>  
        </resource>  
        <resource>  
            <directory>src/main/resources</directory>  
            <includes>  
                <include>\*\*/\*.properties</include>  
                <include>\*\*/\*.xml</include>  
            </includes>  
            <filtering>false</filtering>  
        </resource>  
    </resources>  
    <!-- 为什么只声明:如果在父项目中引入,所有继承的子项目都需要导入所有jar一遍 -->  
    <pluginManagement>  
        <plugins>  
            <plugin>  
                <groupId>org.apache.tomcat.maven</groupId>  
                <artifactId>tomcat7-maven-plugin</artifactId>  
                <version>${tomcat7-maven-plugin-version}</version>  
                <configuration>  
                    <port>8080</port>  
                    <path>/</path>  
                </configuration>  
            </plugin>  
        </plugins>  
    </pluginManagement>  
</build>

<modules>  
    <module>ego1-pojo</module>  
    <module>ego1-service</module>  
    <module>ego1-dubbo</module>  
    <module>ego1-manager</module>  
    <module>ego1-commons</module>  
    <module>ego1-portal</module>  
    <module>ego1-item</module>  
    <module>ego1-search</module>  
    <module>ego1-passport</module>  
    <module>ego1-cart</module>  
</modules>  

8.4 服务者provider配置文件(ego-dubbo)

pom.xml

http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
com.ego ego1-parent 0.0.1-SNAPSHOT
ego1-dubbo

com.ego ego1-service 0.0.1-SNAPSHOT com.alibaba dubbo spring org.springframework org.springframework spring-context com.101tec zkclient com.github.pagehelper pagehelper org.aspectj aspectjweaver org.springframework spring-jdbc org.mybatis mybatis org.mybatis mybatis-spring log4j log4j mysql mysql-connector-java

applicationContext-dubbo.xml


http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">





<!-- 将服务接口发布到注册中心上! -->  
<dubbo:service interface="com.ego.dubbo.service.TbItemDubboService" ref="tbItemDubboServiceImpl"></dubbo:service>  
<!-- class:实现类的全路径 -->  
<bean id="tbItemDubboServiceImpl" class="com.ego.dubbo.service.impl.TbItemDubboServiceImpl"></bean>

<dubbo:service interface="com.ego.dubbo.service.TbItemCatDubboService" ref="tbItemCatDubboServiceImpl"></dubbo:service>  
<bean id="tbItemCatDubboServiceImpl" class="com.ego.dubbo.service.impl.TbItemCatDubboServiceImpl"></bean>

<!-- 商品描述服务 -->  
<dubbo:service interface="com.ego.dubbo.service.TbItemDescDubboService" ref="tbItemDescDubboServiceImpl"></dubbo:service>  
<bean id="tbItemDescDubboServiceImpl" class="com.ego.dubbo.service.impl.TbItemDescDubboServiceImpl"></bean>  
<!-- 商品规格参数查询 -->  
<dubbo:service interface="com.ego.dubbo.service.TbItemParamDubboService" ref="tbItemParamDubboServiceImpl"></dubbo:service>  
<bean id="tbItemParamDubboServiceImpl" class="com.ego.dubbo.service.impl.TbItemParamDubboServiceImpl"></bean>

<!-- 商品规格参数服务  ctrl+c  and  ctrl+v -->  
<dubbo:service interface="com.ego.dubbo.service.TbItemParamItemDubboService" ref="tbItemParamItemDubboServiceImpl"></dubbo:service>  
<bean id="tbItemParamItemDubboServiceImpl" class="com.ego.dubbo.service.impl.TbItemParamItemDubboServiceImpl"></bean>

<!-- 商品分类管理 -->  
<dubbo:service interface="com.ego.dubbo.service.TbContentCategoryDubboService" ref="tbContentCategoryDubboServiceImpl"></dubbo:service>  
<bean id="tbContentCategoryDubboServiceImpl" class="com.ego.dubbo.service.impl.TbContentCategoryDubboServiceImpl"></bean>

<!-- 添加商品内容分类服务 -->  
<dubbo:service interface="com.ego.dubbo.service.TbContentDubboService" ref="tbContentDubboServiceImpl"></dubbo:service>  
<bean id="tbContentDubboServiceImpl" class="com.ego.dubbo.service.impl.TbContentDubboServiceImpl"></bean>

<!-- 添加TbUser服务 -->  
<dubbo:service interface="com.ego.dubbo.service.TbUserDubboService" ref="tbUserDubboServiceImpl"></dubbo:service>  
<bean id="tbUserDubboServiceImpl" class="com.ego.dubbo.service.impl.TbUserDubboServiceImpl"></bean>

<!-- 4.扫描duubo注解,不能使用,替换成配置文件方式来实现.否则和AOP有冲突.最根本的原因就是dubbo@Service无效. -->  
<import resource="classpath:applicationContext-mybatis.xml"/>

8.4 消费者consumer配置文件(这里只提供ego-magager)

pom.xml

http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
com.ego ego1-parent 0.0.1-SNAPSHOT
ego1-manager
war

com.ego ego1-commons 0.0.1-SNAPSHOT com.ego ego1-service 0.0.1-SNAPSHOT javax.servlet javax.servlet-api provided javax.servlet.jsp jsp-api provided jstl jstl org.springframework spring-webmvc org.springframework spring-jdbc log4j log4j commons-fileupload commons-fileupload com.github.pagehelper pagehelper commons-io commons-io com.alibaba dubbo spring org.springframework org.springframework spring-context com.101tec zkclient commons-net commons-net redis.clients jedis
src/main/java **/*.properties **/*.xml false src/main/resources **/*.properties **/*.xml false org.apache.tomcat.maven tomcat7-maven-plugin 8080 /

applicationContext-dubbo.xml


http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

<!-- 1. 应用程序名称 -->  
<dubbo:application name="ego1-manager"/>  
<!-- 2.注册中心地址 -->  
<dubbo:registry  protocol="zookeeper" address="192.168.26.169:2181"></dubbo:registry>  
<!-- 4. 扫描@references -->  
<dubbo:annotation package="com.ego.manager.service.impl"></dubbo:annotation>  

8.5 发布服务到注册中心

打包ego-dubbo项目

  1. 参考dubbo课堂笔记:
  2. 将打完包之后的tar.gz上传到linux服务器。此台linux服务器必须具备tomcat,jdk。
  3. 启动dubbo服务。
  4. 通过tomcat下webapps目录中的dubbo的监控中心可以观察到dubbo是否启动成功!

看到此图说明启动成功!则可以运行eclipse中的任意一个ego中的maven项目。

8.6 部署消费者到Linux

热部署(远程部署)

1、创建一个虚拟机。该虚拟机要有jdk,tomcat。

安装jdk,tomcat。

修改tomcat中  vim tomcat-users.xml

修改完成之后,重启tomcat,访问:http://192.168.26.150:8080/manager/html

2、

将ego-portal项目进行打包放到tomcat服务器上。将这句话添加到portal的pom.xml中。并做修改。

8082

/

tomcat

tomcat

http://192.168.26.150:8080/manager/text

接下来开始部署 tomcat7:redeploy 使用maven bulid…

3、 查看是否部署成功

找到tomcat目录下webapps下ROOT目录下:

查看是否部署成功,lib下是否有jar包。

4、验证是否部署成功

在浏览器就可以直接访问http://192.168.26.150:8080/

5、配置虚拟映射C:\Windows\System32\drivers\etc\hosts

192.168.26.150 www.ego.com 如果不写端口默认是80端口。修改linux 服务器中tomcat的端口号80.需要重启tomcat。通过域名访问即可。

做完虚拟域名之后:完全可以将ego项目进行大修改!

修改所有的url:

ego-portal localhost:8082 变成http://ego.portal.com

ego-item  localhost:8081  ego.item.com

ego-order localhost:8086  ego.order.com

ego-passport  localhost:8084  ego.passport.com

ego-search  localhost:8083  ego.search.com

ego-cart  localhost:8085  ego.cart.com

ego-portal  localhost:8082  ego.portal.com

都部署到linux上,一个项目需要一个虚拟机!!!

8.7 nginx反向代理

8.8 vsftp

8.9 单点登录

9.0 redis