• 2022-07-01 Dubbo&&Zookeeper


    软件结构的演进过程:

    软件架构的发展经历了单体架构、垂直架构、SOA架构、微服务架构的演进过程。

    1、单体架构:

    单体架构中,所有功能代码全部都在同一个部署包中。

    单体架构优点:

    架构简单,前期开发成本低、开发周期短,适合小型项目(OA、CRM、ERP 企业内部应用)

    单体架构缺点:

    1.1.代码模块边界很混乱,只会越来越乱!

    1.2.随着代码的增加,构建和部署的时间也会增加

    1.3.技术革新很难,想要引入新的框架或技术平台非常困难。

    1.4.团队协作难度高,如多人使用 git 很可能在同一个功能上,多人同时进行了修改,作为一个大而全的项目,可能个人只是需要开发其中一个小的模块的需求,却需要导入整个项目全量的代码


    2、垂直架构

    按照业务进行切割,形成小的单体项目。  

    垂直架构优点:技术栈可扩展(不同的系统可以用不同的编程语言编写)

    垂直架构缺点:

    2.1 垂直架构中每一个系统还是单体架构

    2.2 项目之间功能冗余、数据冗余,多个项目中可能要编写重复的功能代码,加载重复的数据。

    项目之间没有联系,导致代码重复,比如三个过程都会要用户和商品代码。


    3、SOA架构
    SOA全称为 "Service-Oriented Architecture",即面向服务的架构。

    它可以根据需求通过网络对松散耦合的粗粒度应用组件(服务)进行分布式部署、组合和使用。一个服务通常以独立的形式存在于操作系统进程中。

    SOA架构的优点

    ① 可重用性高

            重复功能或模块抽取为服务,提高开发效率。

    ② 维护成本低

            修改一个功能,可以直接修改一个项目,单独部署。

    ③ 可扩展性强

            不同的系统可以用不同的语言、不同的技术进行编写。并且可以按照需要,对不同的系统进行集群扩充

    SOA架构的缺点

    ① 抽取服务的粒度大(相对微服务而言)

            各系统之间业务不同,很难确认功能或模块是重复的


    4、微服务架构

    微服务是在 SOA 上做的升华,微服务架构强调的一个重点是“业务需要彻底的组件化和服务化”。

    原有的单个业务系统会拆分为多个可以独立开发、设计、运行的小应用。这些小应用之间通过服务完成交互和集成。

    微服务的优点

    ① 服务拆分粒度更细,遵循单一职责原则,有利于提高开发效率。

    ② 可采用Http协议进行服务间的调用

    ③ 可以针对不同服务制定对应的优化方案,适用于互联网时代,产品迭代周期更短。

    微服务的缺点

    ① 对开发团队技术要求高


    Apache Dubbo

    Apache Dubbo是一款高性能的Java RPC框架。其前身是阿里巴巴公司开源的一个高性能、轻量级的开源Java RPC框架,可以和Spring框架无缝集成。

    Dubbo官网地址:Apache Dubbo

    Dubbo提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

    RPC 远程过程调用

    RPC并不是一个具体的技术,而是指整个网络远程调用过程。

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


    Dubbo  Java中的RPC框架

    Java中的RPC框架比较多,广泛使用的有RMI、Hessian、Dubbo等。

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

    Container:服务运行容器

    1. 服务容器负责启动,加载,运行服务提供者。

    2. 服务提供者在启动时,向注册中心注册自己提供的服务。

    3. 服务消费者在启动时,向注册中心订阅自己所需的服务。

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

    5. 服务消费者,从提供者地址列表中,基于负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。

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

     蓝色虚线:在启动时完成的功能


    服务注册中心Zookeeper

    Dubbo官方推荐使用Zookeeper作为服务注册中心。

    zookeeper为什么能作为注册中心?做注册中心需要有哪些能力?
    1.记录数据(消费者与提供者的地址)
    2.有监控变化,从而及时推送的功能

    Zookeeper

    Zookeeper 是 Apache Hadoop 的子项目,是一个树型的目录服务,支持变更推送,适合作为 Dubbo 服务的注册中心,工业强度较高,可用于生产环境,并推荐使用 。

    Zookeeper树型目录服务:

    流程说明:

    · 服务提供者(Provider)启动时: 向 /dubbo/com.foo.BarService/providers 目录下写入自己的 URL 地址

    · 服务消费者(Consumer)启动时: 订阅 /dubbo/com.foo.BarService/providers 目录下的提供者 URL 地址。并向 /dubbo/com.foo.BarService/consumers 目录下写入自己的 URL 地址

    · 监控中心(Monitor)启动时: 订阅 /dubbo/com.foo.BarService 目录下的所有提供者和消费者 URL 地址

    安装Zookeeper

    下载地址:Index of /dist/zookeeperhttp://archive.apache.org/dist/zookeeper/当然,我直接用老师给的,将压缩包解压到Windows/Linux电脑的没有中文的路径下即可

    配置Zookeeper

    1. conf目录中的zoo_sample.cfg文件复制一份到conf目录并命名为zoo.cfg

    2. 修改zoo.cfg文件: 大概在第12行,设置dataDir=../data

    3. 在zookeeper的安装目录中,创建data目录

    启动、停止Zookeeper

    1. 启动Zookeeper: 进入bin目录,双击zkServer.cmd

    2. 停止Zookeeper: 关闭Zookeeper的DOS窗口


     Dubbo快速上手

     1、开发服务提供者

    创建maven工程用一种神奇的插件把它改成maven形式的web工程,


    然后是在pom文件中导入依赖,,,真的是无语,幸好咱只是复制而已

    1. <packaging>war</packaging>
    2. <properties>
    3. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    4. <maven.compiler.source>1.8</maven.compiler.source>
    5. <maven.compiler.target>1.8</maven.compiler.target>
    6. <spring.version>5.0.5.RELEASE</spring.version>
    7. </properties>
    8. <dependencies>
    9. <dependency>
    10. <groupId>org.springframework</groupId>
    11. <artifactId>spring-webmvc</artifactId>
    12. <version>${spring.version}</version>
    13. </dependency>
    14. <dependency>
    15. <groupId>org.springframework</groupId>
    16. <artifactId>spring-jdbc</artifactId>
    17. <version>${spring.version}</version>
    18. </dependency>
    19. <dependency>
    20. <groupId>org.springframework</groupId>
    21. <artifactId>spring-aspects</artifactId>
    22. <version>${spring.version}</version>
    23. </dependency>
    24. <dependency>
    25. <groupId>org.springframework</groupId>
    26. <artifactId>spring-jms</artifactId>
    27. <version>${spring.version}</version>
    28. </dependency>
    29. <dependency>
    30. <groupId>org.springframework</groupId>
    31. <artifactId>spring-context-support</artifactId>
    32. <version>${spring.version}</version>
    33. </dependency>
    34. <!-- dubbo相关 -->
    35. <dependency>
    36. <groupId>com.alibaba</groupId>
    37. <artifactId>dubbo</artifactId>
    38. <version>2.6.0</version>
    39. </dependency>
    40. <dependency>
    41. <groupId>org.apache.zookeeper</groupId>
    42. <artifactId>zookeeper</artifactId>
    43. <version>3.4.7</version>
    44. </dependency>
    45. <dependency>
    46. <groupId>com.github.sgroschupf</groupId>
    47. <artifactId>zkclient</artifactId>
    48. <version>0.1</version>
    49. </dependency>
    50. <dependency>
    51. <groupId>javassist</groupId>
    52. <artifactId>javassist</artifactId>
    53. <version>3.12.1.GA</version>
    54. </dependency>
    55. <dependency>
    56. <groupId>com.alibaba</groupId>
    57. <artifactId>fastjson</artifactId>
    58. <version>1.2.47</version>
    59. </dependency>
    60. </dependencies>
    61. <build>
    62. <plugins>
    63. <plugin>
    64. <groupId>org.eclipse.jetty</groupId>
    65. <artifactId>jetty-maven-plugin</artifactId>
    66. <version>9.4.15.v20190215</version>
    67. <configuration>
    68. <!-- 如果检测到项目有更改则自动热部署,每隔n秒扫描一次。默认为0,即不扫描-->
    69. <scanIntervalSeconds>2</scanIntervalSeconds>
    70. <webAppConfig>
    71. <!--指定web项目的根路径,默认为/ -->
    72. <contextPath>/</contextPath>
    73. </webAppConfig>
    74. <httpConnector>
    75. <!--端口号,默认 8080-->
    76. <port>8000</port>
    77. </httpConnector>
    78. </configuration>
    79. </plugin>
    80. </plugins>
    81. </build>

    创建提供者服务的接口

    1. public interface HelloService {
    2. public String sayHello(String name);
    3. }

    创建提供者服务的服务实现类

    重点注意这里的@Service注解

    注意`Service`注解要导入`com.alibaba.dubbo.config.annotation.Service`,用于对外发布服务

    1. @Service
    2. public class HelloServiceImpl implements HelloService {
    3. @Override
    4. public String sayHello(String name) {
    5. return "Hello "+name+" , I see you";
    6. }
    7. }

    创建applicationContext-service.xml

    在spring的配置文件,注册服务,创建在src/main/resources下

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    4. xsi:schemaLocation="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">
    5. <!--dubbo的配置:向注册中心注册服务-->
    6. <!--1.配置应用名:要求每一个应用的应用名唯一-->
    7. <dubbo:application name="dubbodemo-provider" />
    8. <!--2.配置注册中心地址-->
    9. <dubbo:registry address="zookeeper://127.0.0.1:2181"/>
    10. <!--
    11. 3.配置rpc协议,name表示协议名,port表示提供者的端口号默认是20880,每一个提供者的端口号应该唯一
    12. -->
    13. <dubbo:protocol name="dubbo" port="20881"/>
    14. <!--
    15. 4. dubbo的包扫描
    16. -->
    17. <dubbo:annotation package="com.atguigu"/>
    18. </beans>

    创建的位置参考图如下:

     通过jetty插件启动服务提供者

    配置web.xml

    让它帮我们启动spring的配置文件

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
    5. version="4.0">
    6. <context-param>
    7. <param-name>contextConfigLocation</param-name>
    8. <param-value>classpath:applicationContext*.xml</param-value>
    9. </context-param>
    10. <listener>
    11. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    12. </listener>
    13. </web-app>

    2、开发服务消费者

    创建服务消费者工程,命名为dubbodemo-consumer,通过插件改成javaweb工程

    pom文件中导入让人无语到极致的依赖,, 

    1. <packaging>war</packaging>
    2. <properties>
    3. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    4. <maven.compiler.source>1.8</maven.compiler.source>
    5. <maven.compiler.target>1.8</maven.compiler.target>
    6. <spring.version>5.0.5.RELEASE</spring.version>
    7. </properties>
    8. <dependencies>
    9. <dependency>
    10. <groupId>org.springframework</groupId>
    11. <artifactId>spring-webmvc</artifactId>
    12. <version>${spring.version}</version>
    13. </dependency>
    14. <dependency>
    15. <groupId>org.springframework</groupId>
    16. <artifactId>spring-jdbc</artifactId>
    17. <version>${spring.version}</version>
    18. </dependency>
    19. <dependency>
    20. <groupId>org.springframework</groupId>
    21. <artifactId>spring-aspects</artifactId>
    22. <version>${spring.version}</version>
    23. </dependency>
    24. <dependency>
    25. <groupId>org.springframework</groupId>
    26. <artifactId>spring-jms</artifactId>
    27. <version>${spring.version}</version>
    28. </dependency>
    29. <dependency>
    30. <groupId>org.springframework</groupId>
    31. <artifactId>spring-context-support</artifactId>
    32. <version>${spring.version}</version>
    33. </dependency>
    34. <!-- dubbo相关 -->
    35. <dependency>
    36. <groupId>com.alibaba</groupId>
    37. <artifactId>dubbo</artifactId>
    38. <version>2.6.0</version>
    39. </dependency>
    40. <dependency>
    41. <groupId>org.apache.zookeeper</groupId>
    42. <artifactId>zookeeper</artifactId>
    43. <version>3.4.7</version>
    44. </dependency>
    45. <dependency>
    46. <groupId>com.github.sgroschupf</groupId>
    47. <artifactId>zkclient</artifactId>
    48. <version>0.1</version>
    49. </dependency>
    50. <dependency>
    51. <groupId>javassist</groupId>
    52. <artifactId>javassist</artifactId>
    53. <version>3.12.1.GA</version>
    54. </dependency>
    55. <dependency>
    56. <groupId>com.alibaba</groupId>
    57. <artifactId>fastjson</artifactId>
    58. <version>1.2.47</version>
    59. </dependency>
    60. </dependencies>
    61. <build>
    62. <plugins>
    63. <plugin>
    64. <groupId>org.eclipse.jetty</groupId>
    65. <artifactId>jetty-maven-plugin</artifactId>
    66. <version>9.4.15.v20190215</version>
    67. <configuration>
    68. <webAppConfig>
    69. <!--指定web项目的根路径,默认为/ -->
    70. <contextPath>/</contextPath>
    71. </webAppConfig>
    72. <httpConnector>
    73. <!--端口号,默认 8080-->
    74. <port>8082</port>
    75. </httpConnector>
    76. </configuration>
    77. </plugin>
    78. </plugins>
    79. </build>

    创建消费者服务接口

    因为和提供者服务接口一样,直接复制就好。(这里明显感觉代码重复了,为一会优化做铺垫)

    1. public interface HelloService {
    2. public String sayHello(String name);
    3. }

    创建HelloController

    Controller中注入HelloService使用的是Dubbo提供的@Reference注解,而不再是我们以前的@Autowired了

    注意这里的@Reference是alibaba包下的

    1. @Controller
    2. @RequestMapping("/demo")
    3. public class HelloController {
    4. @Reference
    5. private HelloService helloService;
    6. @RequestMapping("/hello")
    7. @ResponseBody
    8. public String getName(String name){
    9. //基于接口远程调用服务
    10. String result = helloService.sayHello(name);
    11. System.out.println(result);
    12. return result;
    13. }
    14. }

     创建applicationContext-web.xml

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xmlns:context="http://www.springframework.org/schema/context"
    5. xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    6. xsi:schemaLocation="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">
    7. <!--1. springmvc的配置-->
    8. <!--1.1 包扫描-->
    9. <context:component-scan base-package="com.atguigu"/>
    10. <!--2. dubbo的配置-->
    11. <!--2.1 配置应用名-->
    12. <dubbo:application name="dubbodemo-consumer"/>
    13. <!--2.2 配置注册中心的地址-->
    14. <dubbo:registry address="zookeeper://127.0.0.1:2181"/>
    15. <!--2.3 配置dubbo的包扫描-->
    16. <dubbo:annotation package="com.atguigu"/>
    17. <!--2.4 配置启动时不检查:当启动消费者的时候不检查是否有提供者-->
    18. <dubbo:consumer check="false"/>
    19. </beans>

    创建位置参考:

    消费者服务配置web.xml

    看的我都有点想哭,虽然都学过,也都能看得懂,但是真的烦啊,咋看着这么多

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
    5. version="4.0">
    6. <servlet>
    7. <servlet-name>dispatcherServlet</servlet-name>
    8. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    9. <init-param>
    10. <param-name>contextConfigLocation</param-name>
    11. <param-value>classpath:applicationContext-web.xml</param-value>
    12. </init-param>
    13. <load-on-startup>1</load-on-startup>
    14. </servlet>
    15. <servlet-mapping>
    16. <servlet-name>dispatcherServlet</servlet-name>
    17. <url-pattern>/</url-pattern>
    18. </servlet-mapping>
    19. <!-- 配置过滤器解决 POST 请求的字符乱码问题 -->
    20. <filter>
    21. <filter-name>CharacterEncodingFilter</filter-name>
    22. <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    23. <!-- encoding参数指定要使用的字符集名称 -->
    24. <init-param>
    25. <param-name>encoding</param-name>
    26. <param-value>UTF-8</param-value>
    27. </init-param>
    28. <!-- 请求强制编码 -->
    29. <init-param>
    30. <param-name>forceRequestEncoding</param-name>
    31. <param-value>true</param-value>
    32. </init-param>
    33. <!-- 响应强制编码 -->
    34. <init-param>
    35. <param-name>forceResponseEncoding</param-name>
    36. <param-value>true</param-value>
    37. </init-param>
    38. </filter>
    39. <filter-mapping>
    40. <filter-name>CharacterEncodingFilter</filter-name>
    41. <url-pattern>/*</url-pattern>
    42. </filter-mapping>
    43. </web-app>

    使用jetty插件启动服务消费者

    启动测试

    注意顺序:先启动注册中心,再启动提供者、消费者

    然后在浏览器输入 http://localhost:8082/demo/hello?name=Alice

    查看浏览器输出结果


    优化及一些思考

    记得我前面提过,在服务提供者工程(dubbodemo-provider)和服务消费者工程(dubbodemo-consumer)俩个的HelloService接口是一模一样的。

    解决方案:单独创建一个maven工程,将此接口创建在这个maven工程中。需要依赖此接口的工程只需要在自己工程的pom.xml文件中引入maven坐标即可。

    在服务消费者工程(dubbodemo-consumer)中只是引用了HelloService接口,并没有提供实现类,Dubbo是如何做到远程调用的?

    答:Dubbo底层是基于代理技术为HelloService接口创建代理对象,远程调用是通过此代理对象完成的。

    Zookeeper服务这么重要 ,如何防止Zookeeper单点故障呢?

    答:Zookeeper其实是支持集群模式的,可以配置Zookeeper集群来达到Zookeeper服务的高可用,防止出现单点故障


    创建工程service-api,

    pom文件也是什么依赖都没有引入,干干净净

    创建HelloService接口,参考位置如下:

     

    最终

    ① 删除服务提供者和服务消费者中的HelloService接口

    ② 在服务提供者和服务消费者的pom.xml中添加依赖service-api

    1. <dependency>
    2. <groupId>com.atguigu</groupId>
    3. <artifactId>service-api</artifactId>
    4. <version>1.0-SNAPSHOT</version>
    5. </dependency>

     重新启动服务,测试是没问题的,我还是经得住考验的!


    Dubbo管理控制台 

    搭建监控中心,实则就是一个war包。

    那怎么运行一个war包呢?

    将dubbo-admin-2.6.0.war文件复制到tomcat的webapps目录下,启动Tomcat,此时war文件会自动解压

    进入解压的目录中修改WEB-INF下的dubbo.properties文件

    1.我们取巧,先启动tomcat,这样就能让tomcat帮我们解压这个war包了,我们再关了tomcat,“X”掉小黑窗,把这个解压的war包删了(这步很重要)

    去bin目录下找到,双击启动tomcat

    2.进入解压的目录中修改WEB-INF下的dubbo.properties文件

    1. dubbo.registry.address=zookeeper://127.0.0.1:2181
    2. dubbo.admin.root.password=root
    3. dubbo.admin.guest.password=root

     注意dubbo.registry.address对应的值需要对应当前使用的Zookeeper的ip地址和端口号

  • 相关阅读:
    【软考软件评测师】第二十章 计算机组成与体系结构(CPU指令系统)
    vxe-table表格校验失败后保持可以编辑状态
    常用命令记录
    极简试用期转正述职报告PPT模板
    Adaptive AUTOSAR CM模块介绍(三)
    Python GDAL库在Anaconda环境中的配置
    nginx多端口多server_name监听同时支持https和http
    【深度学习】基于卷积神经网络(tensorflow)的人脸识别项目(一)
    golang中给数据库datetime格式赋值
    【G-LAB】带你掌握网络交换机上各种接口知识
  • 原文地址:https://blog.csdn.net/m0_56799642/article/details/125563869