新手如何学习dubbo框架?

一、传统系统架构模式

	主要三层架构:表现层 、业务逻辑层 、数据访问层
	存在不足之处:
		所有的代码在同一个项目中不方便维护,比如:100个类写在同一个包下
		所有的项目都会使相同的一个代码库,当程序员提交一些错误代码,改动代码,当内容增多,效率变得低下。
		商业价值:防止被别人偷取代码,直接影响公司的利益。
		多模块之间相互依赖,把所有的包变成一个项目,
		三层架构难免也存在责任交叉,某些地方的改动可能会带来其他层会同步变动,失去了分层的独立性。
		单系统只能用一种开发语言,不能用多种开发技术

1.1 存在以上这么多的不足,那么怎么解决呢?

  采用微服务方式:
	a、将产品或者项目分解为众多独立的服务,这些服务独立的部署,并且不依赖与其他服务,就相当于把一个项目的各个模
	块分解为不同的微服务进行项目部署
	b、单系统只能用一种开发语言,但微服务每个独立服务,因此每个模块可以利用不同的技术开发,比如商品模块用SSM框
	架,订单模块用SSH框架
	c、开发集中在一个服务,业务和代码量都不大,开发人员更好的把握代码招不同的开发人员开发项目,提高公司的利润,
	不同的人做不同的事情,开发公司成本是很重要的,如果一个公司都只会SSM框架,成本很高,肯定会招一些小弟开发项
	目节约成本。

1.2 微服务也存在一些问题,怎么解决呢?

	因为每个功能都是独立的服务,因此在一个较大的项目中,检测管理服务变得更加复杂,如果某一个服务出错的话,调试
	跟踪比单系统更加复杂,因此建立统一的日志管理系统可能是目前解决这问题的最佳方案。那么可以采用dubbo(rpc技术)
	框架  、Spring Cloud框架

二、Dubbo框架

2.1 dubbo简介

	是一个分布式服务治理框架,提供高性能和透明化的RPC远程服务调用方案,可以和Spring无缝集成,是阿里巴巴SOA服
	务化治理方案的核心框架,每天为2000+服务提供3亿次访问量支持
	它采用的是一种非常简单的模型,要么是提供服务,要么是消费服务,所以基于这一点抽象出服务提供方(Provider) 和 服
	务消费方(Consumer)两个角色
	主要解决以下问题:
		服务注册中心来管理服务提供方提供的接口,那么服务消费方到注册中心获取提供方提供的接口。
	        当dubbo开源后,当当网根据自身的需求,为Dubbo实现了一些新的功能,

2.2 Dubbo的核心要点:

	服务监控:无论是哪一方,他们都需要对服务调用的实际状态进行有效的监控,从而改进服务质量。
			远程通信与信息交换:双方约点的协议
	服务定义:围绕服务提供方和消费方,服务提供方实现服务,服务消费方调用服务
	服务注册:通过服务统一管理,比如Spring 管理整个项目,这些服务会被居中管理,Dubbo提供的注册中心有四种类型:
			Multicast(多播/组播)注册中心
			Zookeeper注册中心
			Redis注册中心
			Simle注册中心
			步骤:
				提供方提供服务到注册中心,消费方到注册中心调用提供方的服务,这里的服务就是接口。
				在调用的时候可以监控调用是否成功,调用几次。监控中心

2.3 怎么做到分布式应用,怎么做到单项目变成多项目,可怎么做到让一个项目负载均衡?可以让以前的老项目变成dubbo项目?

2.3.1 Dubbo-parent:

实际操作步骤:
	a、看官方maven仓库
	b、Dubbo-parent:		
		导包,放在父类,子类也会依赖,是它的作用多模块那么就需要一个父模块,下面有很多子模块,父类什么都不做,
		只是负责依赖jar包,创建maven项目
	c、pom.xml配置和dubbo-api公共代码
	d、两个不同的项目怎么交流呢?就好比有两个提供者
		通过RPC技术
	该接口需要单独打包,提供方和消费方需要共享
	再创建一个dubbo-api  公共的代码。注意需要相互依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>dubbo-provider</groupId>
    <artifactId>dubbo-provider</artifactId>
    <version>1.0-SNAPSHOT</version>


    <dependencies>


        <!--dubbo 阿里巴巴分布式应用框架-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.6.2</version>
        </dependency>


        <dependency>
            <groupId>dubbo-api</groupId>
            <artifactId>dubbo-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>


        <!-- junit测试包-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.3.16.RELEASE</version>
        </dependency>

        <!-- zk 客户端-->
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.1</version>
        </dependency>


    </dependencies>


    <!-- 打包jar详细配置 -->
    <build>
        <!-- jar包名字 -->
        <finalName>provder</finalName>
        <!-- 打包资源配置,如配置文件 -->
        <resources>
            <resource>
                <targetPath>${project.build.directory}/classes</targetPath>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
            </resource>
            <!-- 结合com.alibaba.dubbo.container.Main
            官方文档:dubbo会自动在classes/META-INF/spring下去加载spring的配置文件
            因此打包时需要将spring配置文件复制到该目录
            -->
            <resource>
                <targetPath>${project.build.directory}/classes/META-INF/spring</targetPath>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
                <includes>
                    <include>provider.xml</include>
                </includes>
            </resource>
        </resources>

        <pluginManagement>
            <plugins>
                <!-- 解决Maven插件在Eclipse内执行了一系列的生命周期引起冲突 -->
                <plugin>
                    <groupId>org.eclipse.m2e</groupId>
                    <artifactId>lifecycle-mapping</artifactId>
                    <version>1.0.0</version>
                    <configuration>
                        <lifecycleMappingMetadata>
                            <pluginExecutions>
                                <pluginExecution>
                                    <pluginExecutionFilter>
                                        <groupId>org.apache.maven.plugins</groupId>
                                        <artifactId>maven-dependency-plugin</artifactId>
                                        <versionRange>[2.0,)</versionRange>
                                        <goals>
                                            <goal>copy-dependencies</goal>
                                        </goals>
                                    </pluginExecutionFilter>
                                    <action>
                                        <ignore />
                                    </action>
                                </pluginExecution>
                            </pluginExecutions>
                        </lifecycleMappingMetadata>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
        <plugins>
            <!-- 打包jar文件时,配置manifest文件,加入lib包的jar依赖 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <classesDirectory>target/classes/</classesDirectory>
                    <archive>
                        <manifest>
                            <mainClass>com.alibaba.dubbo.container.Main</mainClass>
                            <!-- 重要:打包时 MANIFEST.MF文件不记录的时间戳版本 -->
                            <useUniqueVersions>false</useUniqueVersions>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>lib/</classpathPrefix>
                        </manifest>
                        <manifestEntries>
                            <Class-Path>.</Class-Path>
                        </manifestEntries>
                    </archive>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <type>jar</type>
                            <includeTypes>jar</includeTypes>
                          <!--  <useUniqueVersions>false</useUniqueVersions>-->
                            <outputDirectory>
                                ${project.build.directory}/lib
                            </outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>

    </build>
</project>

=============================================================
public interface DemoService {
    String sayHello(String name);
    void  save(User user);
}

 
@Service
public class DemoServiceImpl implements DemoService {

    public String sayHello(String name) {
        return "Hello " + name;
    }

    public void save(User user) {
        System.out.println(user.getName());
    }
}
=======================================================

public class User implements Serializable {

    private Integer id;
    private String name;

 setter / getter 方法
}


2.3.2 Dubbo-order: 服务提供者

a、定义服务接口
b、在服务提供方实现该接口
	上面两部已经被抽取到父类中
c、在resources下新建provider.xml   需要给Spring集成
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd        http://dubbo.apache.org/schema/dubbo        http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="dubbo-order"  />

    <!-- 使用multicast广播注册中心暴露服务地址 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181"  client="zkclient"/>

    <!-- 用dubbo协议在20880端口暴露服务 -->
    <dubbo:protocol name="dubbo" port="20880" />

    <!-- 声明需要暴露的服务接口
    <dubbo:service interface="cn.itsource.DemoService" ref="demoService"  owner="zs" />-->

    <!-- 和本地bean一样实现服务
    <bean id="demoService" class="cn.itsource.DemoServiceImpl" /> -->
    <!-- 注解  -->
    <dubbo:annotation package="cn.itsource" />
  加载Spring的配置:启动	
 

public class Provider2 {
    public static void main(String[] args) throws Exception {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"provider.xml"});
        context.start();
        System.out.println("服务发布成功");
        System.in.read(); // 按任意键退出
    }
    还可以使用Junit4测试启动
    接下来可以在管理中心和检测中心查看
}
</beans>

2.3.3 Dubbo-user:服务消费者

a、通过Spring配置引用远程服务
public class Consumer {
    public static void main(String[] args) throws Exception {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"consumer.xml"});
        context.start();
        DemoService demoService = (DemoService)context.getBean("demoService"); // 获取远程服务代理
        String hello = demoService.sayHello("world"); // 执行远程方法
        System.out.println( hello ); // 显示调用结果
    }
}

2.3.4 Dubbo服务打包:

Dubbo服务的运行方式:
	使用servlet(不推荐)
	Java的main方法(不建议,本地调用可以用)
	Dubbo框架的main方法
Dubbo服务Jar包运行:
	Cmd窗口:
		定位到jar包所在的目录
		输入: java –jar xxxx.jar

2.3.5 Dubbo管理控制台:

对提供方的服务以及消费方的服务进行管理
管理员有禁用服务启用服务的权限
Dubbo-admin部署配置
   启动管理控制台  bin/startup.bat
   通过浏览器访问管理控制台http://127.0.0.1:端口
   默认用户名及密码 : root root  guest guest

2.3.6 Dubbo监控中心:

监控中心负责为服务的监控运维采集各维度的数据,统计各服务的调用次数、时间等,统计先在服务端和消费端内存中汇总,
每隔一分钟发送到监控中心服务器,并以报表的形式展现。

2.3.7 负载均衡:

如果有两个提供者,那么消费者怎么操作的呢?
	注意:名称 、端口 不能一样
随机访问策略 、轮询 、
如果一个提供方代码错误的话,那怎么办?
不放在注册中心,那么就出现直连调试模式,在开发测试环境下,可以绕过注册中心,通过xml配置,
那么一定要注册它,怎么办?
也通过xml配置,直接访问提供者,在消费方直接直连,配置路径需要地址

** 三、Zookper注册中心:**

3.1 zookper注册中心和组播注册中心的区别

	zookper注册中心:   健康检查、当管理员真的禁用的时候就直接禁用了,主要用在项目开发中
	组播注册中心 :如果使用组播注册中心的话需要一定的时间才能消失,不能及时禁用,  主要用在测试中
	步骤:
		修改注册中心地址  2.3以后需要配置客户端
		<dubbo:registry address="zookeeper://127.0.0.1:2181"></dubbo:registry>

		下载包 依赖完之后
		http://mirrors.cnnic.cn/apache/zookeeper/

		安装zookper  在里面启动
		测试zookper注册中心	:先启动服务提供者,再启动服务消费者
		
		使用注解的话,在消费方调用接口的时候不能使用autowired注入了,而是使用reference
		但是可以在其他地方使用autowired注入提供方的试下类需要配置阿里巴巴的service,
		不是spring的service了,Spring的service是父类,没有阿里巴巴的service强大,
		还需要配置在xml中配置注解配置

3.2 监控中心的作用及特点:

个性化运维:服务的健康情况、服务压力及性能分析、告警通知
扩展接口:com.alibaba.dubbo.monitor.MonitorFactory
         com.alibaba.dubbo.monitor.Monitor

** 四、 不同项目区间怎么使用dubbo框架连接?**

如果两个不同的项目 ,就有两个不同的数据库,都有自己的user表,怎么使用在同一个项目中,让一方提供一个接口,
另一方直接调用接口就行
只要是一个实现接口的实现类都要实现序列化接口,因为两个是通过网络传输的,底层是二进制实现的,达到网络传输速度快

4.1 实现步骤:

提供一个api	
导dubbo的jar包
配置文件.xml
提供一个api里面提供一个接口,需要配置Pom.xml
让项目方来实现这个接口
不同的工作区间需要打包,直接把这个包给注册中心,到时候到本地仓库里面去找
需要在spring-croe中引入配置文件
启动

五、面试题:

5.1 如何实现Dubbo的本地调试?

先取消连接注册中心,配置服务为直连模式绕过注册中心,从而实现本地调用,直接连接提供方的服务。
当服务调试稳定后,再使用Zookeeper注册中心,并把服务发布出去。

5.2 Dubbo的核心理念是什么?

① 服务定义、② 服务注册、③ 服务监控、④ 远程通信与信息交换、⑤ 服务调用

5.3 Dubbo的注册中心的作用是什么?

对于服务提供方,它需要发布服务,由于应用系统的复杂性,服务的数量、类型也不断膨胀;对于服务消费方,
它最关心如何获取到它所需要的服务,而面对复杂的应用系统,需要管理大量的服务调用。而且,
对于服务提供方和服务消费方来说,他们还有可能兼具这两种角色,既需要提供服务,又需要消费服务。
通过将服务统一管理起来,可以有效地优化内部应用对服务发布/使用的流程和管理。服务注册中心可以通过特定协议
来完成服务对外的统一

5.4 Dubbo监控中心是干嘛的?

监控中心负责为服务的监控运维采集各维度的数据,统计各服务的调用次数、时间等,统计先在服务端和消费端内存中汇总,	
每隔一分钟发送到监控中心服务器,并以报表的形式展现。
监控中心是独立于服务和管理控制台的,在整个dubbo服务治理环节不是必须的,用户可根据实际情况选择性安装。
监控中心如果出现异常(宕机),并不会影响提供方和消费方之间的服务调用,会丢失故障期间的监控数据,
再生产环境不会有任何风险。

5.5 谈谈你对Zookeeper的理解?

ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,
是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、
分布式同步、组服务等。
ZooKeeper代码版本中,提供了分布式独享锁、选举、队列的接口。
Zookeeper作为Dubbo服务的注册中心,Dubbo原先基于数据库的注册中心,没采用Zookeeper,Zookeeper一个分布式的服务
框架,是树型的目录服务的数据存储,能做到集群管理数据 ,这里能很好的作为Dubbo服务的注册中心,Dubbo能与
Zookeeper做到集群部署,当提供者出现断电等异常停机时,Zookeeper注册中心能自动删除提供者信息,当提供者重启时,能
自动恢复注册数据,以及订阅请求。我们先在windows上安装Zookeeper,我们安装最简单的单点,集群有兴趣的同学可以查找
资料利用虚拟机搭建。

猜你喜欢

转载自blog.csdn.net/weixin_42075468/article/details/83870463