08-架构演变及Dubbo使用回顾

一、项目架构演变过程

随着互联网的发展,用户群体逐渐壮大,网站的流量成倍增长,常规的单体架构已无法满足请求压力暴增和业务的快速迭代,架构的变化势在必行。

1.1、单体架构

单体架构所有模块和功能都集中在一个项目中 ,部署时也是将项目所有功能部整体署到服务器中。如下图:

优点

小项目开发快 成本低

架构简单

易于测试

易于部署

缺点

大项目模块耦合严重 不易开发 维护 沟通成本高

新增业务困难

核心业务与边缘业务混合在一块,出现问题互相影响

1.2、垂直架构

根据业务把项目垂直切割成多个项目,因此这种架构称之为垂直架构。

为了避免上面提到的那些问题,我们开始做模块的垂直划分,做垂直划分的原则是基于拉勾的业务特性,核心目标,第一个是为了业务之间互不影响,第二个是在研发团队的壮大后为了提高效率,减少之间的依赖。

优点

系统拆分实现了流量分担,解决了并发问题

可以针对不同系统进行优化

方便水平扩展,负载均衡,容错率提高

系统间相互独立,互不影响,新的业务迭代时更加高效

缺点

服务系统之间接口调用硬编码

搭建集群之后,实现负载均衡比较复杂

服务系统接口调用监控不到位 调用方式不统一

服务监控不到位

数据库资源浪费,充斥慢查询,主从同步延迟大

1.3、分布式-SOA架构

1.3.1、分布式-SOA介绍

SOA全称为Service Oriented Architecture,即面向服务的架构 。它是在垂直划分的基础上,将每个项目拆分出多个具备松耦合的服务,一个服务通常以独立的形式存在于操作系统进程中。各个服务之间通过网络调用,这使得构建在各种各样的系统中的服务可以 以一种统一和通用的方式进行交互。

我们在做了垂直划分以后,模块随之增多,系统之间的RPC逐渐增多,维护的成本也越来越高,一些通用的业务和模块重复的也越来越多,这个时候上面提到的接口协议不统一、服务无法监控、服务的负载均衡等问题更加突出,为了解决上面的这些问题,我们将通用的业务逻辑下沉到服务层,通过接口暴露,供其他业务场景调用。同时引入了阿里巴巴开源的Dubbo,一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

解释说明:

分层: 按照业务性质分层 每一层要求简单 和 容易维护

应用层:

距离用户最近的一层 也称之为接入层 使用tomcat 作为web容器 接收用户请求 使用下游的dubbo提供的接口来返回数据 并且该层禁止访问数据库

业务服务层:

根据具体的业务场景 演变而来的模块 比如 简历投递 职位搜索 职位推荐等

基础业务层:

拉勾网招聘业务的核心 账号 简历 公司 职位

基础服务层:

这一层 是与业务无关的模块 是一些通用的服务

这类服务的特点:请求量大 逻辑简单 特性明显 功能独立

消息服务(发邮件 短信 微信)

附件解析 50% 自己上传附件简历 需要解析成pdf

存储层:

不同的存储类型 Mysql Mongodb ES fastDFS

分级:按照业务性质分层 同一层的业务也要做好分级 依据业务的重要性进行分级 按照二八定律 网站80%的流量 都在核心功能上面 要优先保证核心业务的稳定。

隔离:不同性质 不同重要性的业务做好隔离 包括 业务 缓存 DB 中间件 都要做好隔离 比如 核心业务的数据库 要和活动相关的数据库隔离

调用 :总体上调用要单向 可以跨层调用 但不能出现逆向调用

1.3.2、分布式-SOA优缺点和微服务

优点

服务以接口为粒度,为开发者屏蔽远程调用底层细节 使用Dubbo 面向接口远程方法调用 屏蔽了底层调用细节

业务分层以后架构更加清晰 并且每个业务模块职责单一 扩展性更强

数据隔离,权限回收,数据访问都通过接口 让系统更加稳定 安全

服务应用本身无状态化 这里的无状态化指的是应用本身不做内存级缓存 而是把数据存入db

服务责任易确定 每个服务可以确定责任人 这样更容易保证服务质量和稳定

缺点

1.粒度控制复杂 如果没有控制好服务的粒度 服务的模块就会越来越多 就会引发 超时 分布式事务等问题

2.服务接口数量不宜控制 容易引发接口爆炸 所以服务接口建议以业务场景进行单位划分 并对相近的业务做抽象 防止接口爆炸

3.版本升级兼容困难 尽量不要删除方法 字段 枚举类型的新增字段也可能不兼容

4.调用链路长 服务质量不可监控 调用链路变长 下游抖动可能会影响到上游业务 最终形成连锁反应 服务质量不稳定 同时链路的变成使得服务质量的监控变得困难

1.4、微服务架构

微服务架构是一种将单个应用程序 作为一套小型服务开发的方法,每种应用程序都在其自己的进程中独立运行,并使用轻量级机制(通常是HTTP资源的API)进行通信。这些服务是围绕业务功能构建的,可以通过全自动部署机制进行独立部署。这些服务的集中化管理非常少,它们可以用不同的编程语言编写,并使用不同的数据存储技术。

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

关于微服务架构的知识,后面Spring Cloud课程中会详细讲解。

二、Dubbo 架构与实战

2.1 Dubbo 架构概述

2.1.1 什么是Dubbo

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

2.1.2 dubbo 的特性

参考官网首页特性

2.1.3 Dubbo 的服务治理

服务治理(SOA governance),企业为了确保项目顺利完成而实施的过程,包括最佳实践、架构原则、治理规程、规律以及其他决定性的因素。服务治理指的是用来管理SOA的采用和实现的过程。

2.2. Dubbo 处理流程

调用关系说明:

虚线 代表异步调用 实线代表同步访问

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

红色虚线 是程序运行中执行的功能

调用流程:

1.服务提供者在服务容器启动时 向注册中心 注册自己提供的服务

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

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

4.服务消费者 从提供者地址列表中 基于软负载均衡算法 选一台提供者进行调用 如果调用失败 则重新选择一台

5.服务提供者和消费者 在内存中的调用次数 和 调用时间 定时每分钟发送给监控中心

2.3、服务注册中心Zookeeper

通过前面的Dubbo架构图可以看到,Registry(服务注册中心)在其中起着至关重要的作用。Dubbo官

方推荐使用Zookeeper作为服务注册中心。Zookeeper 是 Apache Hadoop 的子项目,作为 Dubbo 服

务的注册中心,工业强度较高,可用于生产环境,并推荐使用 。

Zookeeper的安装及其使用见上一模块,此处不再赘述。

2.4 、Dubbo开发实战

2.4.1 实战案例介绍

在Dubbo中所有的的服务调用都是基于接口去进行双方交互的。双方协定好Dubbo调用中的接口,提供者来提供实现类并且注册到注册中心上

调用方则只需要引入该接口,并且同样注册到相同的注册中心上(消费者)。即可利用注册中心来实现集群感知功能,之后消费者即可对提供者进行调用。

我们所有的项目都是基于Maven去进行创建,这样相互在引用的时候只需要以依赖的形式进行展现就可以了。

并且这里我们会通过maven的父工程来统一依赖的版本。

程序实现分为以下几步骤:

(1)建立maven工程 并且 创建API模块: 用于规范双方接口协定

(2)提供provider模块,引入API模块,并且对其中的服务进行实现。将其注册到注册中心上,对外来统一提供服务。

(3)提供consumer模块,引入API模块,并且引入与提供者相同的注册中心。再进行服务调用。

2.4.2 Annotation 的开发过程

2.4.2.1 接口协定 模块

1.定义maven

<groupId>com.lagou</groupId>

<artifactId>service-api</artifactId>

<version>1.0-SNAPSHOT</version>

<properties>

    <dubbo.version>2.7.5 </dubbo.version>

</properties>

<dependencyManagement>

    <dependencies>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo</artifactId>

            <version>${dubbo.version}</version>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo-common</artifactId>

            <version>${dubbo.version}</version>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo-registry-zookeeper</artifactId>

            <version>${dubbo.version}</version>

            <exclusions>

                <exclusion>

                    <groupId>org.apache.dubbo</groupId>

                    <artifactId>dubbo-remoting-api</artifactId>

                </exclusion>

                <exclusion>

                    <groupId>org.apache.dubbo</groupId>

                    <artifactId>dubbo-common</artifactId>

                </exclusion>

            </exclusions>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo-registry-nacos</artifactId>

            <version>${dubbo.version}</version>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo-rpc-dubbo</artifactId>

            <version>${dubbo.version}</version>

            <exclusions>

                <exclusion>

                    <groupId>org.apache.dubbo</groupId>

                    <artifactId>dubbo-remoting-api</artifactId>

                </exclusion>

                <exclusion>

                    <groupId>org.apache.dubbo</groupId>

                    <artifactId>dubbo-common</artifactId>

                </exclusion>

            </exclusions>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo-remoting-netty4</artifactId>

            <version>${dubbo.version}</version>

            <exclusions>

                <exclusion>

                    <groupId>org.apache.dubbo</groupId>

                    <artifactId>dubbo-remoting-api</artifactId>

                </exclusion>

            </exclusions>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo-serialization-hessian2</artifactId>

            <version>${dubbo.version}</version>

            <exclusions>

                <exclusion>

                    <groupId>org.apache.dubbo</groupId>

                    <artifactId>dubbo-common</artifactId>

                </exclusion>

            </exclusions>

        </dependency>

    </dependencies>

</dependencyManagement>

<dependencies>

    <!-- 日志配置 -->

    <dependency>

        <groupId>log4j</groupId>

        <artifactId>log4j</artifactId>

        <version>1.2.16</version>

    </dependency>

    <dependency>

        <groupId>org.slf4j</groupId>

        <artifactId>slf4j-api</artifactId>

        <version>1.7.5</version>

    </dependency>

    <dependency>

        <groupId>org.slf4j</groupId>

        <artifactId>slf4j-log4j12</artifactId>

        <version>1.7.5</version>

    </dependency>

    <!-- json数据化转换 -->

    <dependency>

        <groupId>com.alibaba</groupId>

        <artifactId>fastjson</artifactId>

        <version>1.2.62</version>

    </dependency>

</dependencies>

<build>

    <plugins>

        <plugin>

            <groupId>org.apache.maven.plugins</groupId>

            <artifactId>maven-compiler-plugin</artifactId>

            <version>3.3</version>

            <configuration>

                <source>1.8</source>

                <target>1.8</target>

            </configuration>

        </plugin>

    </plugins>

</build>

2.4.2.2 接口提供者(service-api module)

定义接口,这里为了方便,只是写一个基本的方法。

package com.lagou.service;

public interface HelloService {

    String sayHello(String name);

}

2.4.2.3 提供者(service-providermodule)

1.pom文件

<?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">

    <parent>

        <artifactId>duboo-base-annotation</artifactId>

        <groupId>com.lagou</groupId>

        <version>1.0-SNAPSHOT</version>

    </parent>

    <modelVersion>4.0.0</modelVersion>

    <artifactId>service-provider</artifactId>

    <dependencies>

        <dependency>

            <groupId>com.lagou</groupId>

            <artifactId>service-api</artifactId>

            <version>1.0-SNAPSHOT</version>

        </dependency>

        <dependency>

            <groupId>org.apache.curator</groupId>

            <artifactId>curator-recipes</artifactId>

            <version>4.0.1</version>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo</artifactId>

        </dependency>

        <dependency>

            <groupId>org.apache.curator</groupId>

            <artifactId>curator-recipes</artifactId>

            <version>4.2.0</version>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo-registry-zookeeper</artifactId>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo-rpc-dubbo</artifactId>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo-remoting-netty4</artifactId>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo-serialization-hessian2</artifactId>

        </dependency>

    </dependencies>

</project>

2.service 的实现

package com.lagou.service.impl;

import com.lagou.service.HelloService;

import org.apache.dubbo.config.annotation.Service;

@Service

public class HelloServiceImpl  implements HelloService {

    @Override

    public String sayHello(String name) {

//        try {

//            Thread.sleep(3000);

//        } catch (InterruptedException e) {

//            e.printStackTrace();

//        }

        return "hello:"+name;

    }

}

3.启动类

package com.lagou;

import org.apache.dubbo.config.RegistryConfig;

import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.PropertySource;

public class DubboPureMain {

    public static void main(String[] args) throws  Exception{

        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ProviderConfiguration.class);

        context.start();

        System.in.read();

    }

    @Configuration

    @EnableDubbo(scanBasePackages = "com.lagou.service.impl")

    @PropertySource("dubbo-provider.properties")

    static  class  ProviderConfiguration{

        @Bean

        public RegistryConfig  registryConfig(){

            RegistryConfig  registryConfig  = new RegistryConfig();

            registryConfig.setAddress("zookeeper://127.0.0.1:2181?timeout=10000");

            //registryConfig.setTimeout(10000);

            return  registryConfig;

        }

    }

}

4.配置

dubbo.application.name=dubbo-demo-annotation-provider

dubbo.protocol.name=dubbo

dubbo.protocol.port=20880

2.4.2.4 编写服务消费者

1.pom文件

<?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">

    <parent>

        <artifactId>duboo-base-annotation</artifactId>

        <groupId>com.lagou</groupId>

        <version>1.0-SNAPSHOT</version>

    </parent>

    <modelVersion>4.0.0</modelVersion>

    <artifactId>service-commuser</artifactId>

    <dependencies>

        <dependency>

            <groupId>com.lagou</groupId>

            <artifactId>service-api</artifactId>

            <version>1.0-SNAPSHOT</version>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo</artifactId>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo-registry-zookeeper</artifactId>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo-rpc-dubbo</artifactId>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo-remoting-netty4</artifactId>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo-serialization-hessian2</artifactId>

        </dependency>

    </dependencies>

</project>

2.service 的实现

package com.lagou.bean;

import com.lagou.service.HelloService;

import org.apache.dubbo.config.annotation.Reference;

import org.springframework.stereotype.Component;

@Component

public class ComsumerComponet {

    @Reference

    private HelloService helloService;

    public String sayHello(String name){

        return helloService.sayHello(name);

    }

}

3.启动类

package com.lagou;

import com.lagou.bean.ComsumerComponet;

import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.PropertySource;

import java.io.IOException;

public class AnnotationConsumerMain {

    public static void main(String[] args) throws IOException {

        System.out.println("------");

        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConsumerConfiguration.class);

        context.start();

        ComsumerComponet service = context.getBean(ComsumerComponet.class);

        while (true){

            System.in.read();

            String hello = service.sayHello("world");

            System.out.println("result:"+hello);

        }

    }

    @Configuration

    @PropertySource("classpath:/dubbo-consumer.properties")

    @ComponentScan(basePackages =  "com.lagou.bean" )

    @EnableDubbo

    static class ConsumerConfiguration{

    }

}

2.4.3 xml 的开发过程

2.4.3.1 接口协定 模块

1.定义maven

<?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>com.lagou</groupId>

    <artifactId>dubbo-base-xml</artifactId>

    <packaging>pom</packaging>

    <version>1.0-SNAPSHOT</version>

    <modules>

        <module>service-api-xml</module>

        <module>service-provider-xml</module>

        <module>service-conusumer-xml</module>

    </modules>

    <properties>

        <dubbo.version>2.7.5</dubbo.version>

    </properties>

    <dependencyManagement>

        <dependencies>

            <dependency>

                <groupId>org.apache.dubbo</groupId>

                <artifactId>dubbo</artifactId>

                <version>${dubbo.version}</version>

                <exclusions>

                    <exclusion>

                        <groupId>org.apache.dubbo</groupId>

                        <artifactId>dubbo-common</artifactId>

                    </exclusion>

                </exclusions>

            </dependency>

            <dependency>

                <groupId>org.apache.dubbo</groupId>

                <artifactId>dubbo-common</artifactId>

                <version>${dubbo.version}</version>

            </dependency>

            <dependency>

                <groupId>org.apache.dubbo</groupId>

                <artifactId>dubbo-registry-zookeeper</artifactId>

                <version>${dubbo.version}</version>

                <exclusions>

                    <exclusion>

                        <groupId>org.apache.dubbo</groupId>

                        <artifactId>dubbo-remoting-api</artifactId>

                    </exclusion>

                    <exclusion>

                        <groupId>org.apache.dubbo</groupId>

                        <artifactId>dubbo-common</artifactId>

                    </exclusion>

                </exclusions>

            </dependency>

            <dependency>

                <groupId>org.apache.dubbo</groupId>

                <artifactId>dubbo-registry-nacos</artifactId>

                <version>${dubbo.version}</version>

            </dependency>

            <dependency>

                <groupId>org.apache.dubbo</groupId>

                <artifactId>dubbo-rpc-dubbo</artifactId>

                <version>${dubbo.version}</version>

                <exclusions>

                    <exclusion>

                        <groupId>org.apache.dubbo</groupId>

                        <artifactId>dubbo-remoting-api</artifactId>

                    </exclusion>

                    <exclusion>

                        <groupId>org.apache.dubbo</groupId>

                        <artifactId>dubbo-common</artifactId>

                    </exclusion>

                </exclusions>

            </dependency>

            <dependency>

                <groupId>org.apache.dubbo</groupId>

                <artifactId>dubbo-remoting-netty4</artifactId>

                <version>${dubbo.version}</version>

                <exclusions>

                    <exclusion>

                        <groupId>org.apache.dubbo</groupId>

                        <artifactId>dubbo-remoting-api</artifactId>

                    </exclusion>

                </exclusions>

            </dependency>

            <dependency>

                <groupId>org.apache.dubbo</groupId>

                <artifactId>dubbo-serialization-hessian2</artifactId>

                <version>${dubbo.version}</version>

                <exclusions>

                    <exclusion>

                        <groupId>org.apache.dubbo</groupId>

                        <artifactId>dubbo-common</artifactId>

                    </exclusion>

                </exclusions>

            </dependency>

        </dependencies>

    </dependencyManagement>

    <dependencies>

        <!-- 日志配置 -->

        <dependency>

            <groupId>log4j</groupId>

            <artifactId>log4j</artifactId>

            <version>1.2.16</version>

        </dependency>

        <dependency>

            <groupId>org.slf4j</groupId>

            <artifactId>slf4j-api</artifactId>

            <version>1.7.5</version>

        </dependency>

        <dependency>

            <groupId>org.slf4j</groupId>

            <artifactId>slf4j-log4j12</artifactId>

            <version>1.7.5</version>

        </dependency>

        <!-- json数据化转换 -->

        <dependency>

            <groupId>com.alibaba</groupId>

            <artifactId>fastjson</artifactId>

            <version>1.2.62</version>

        </dependency>

    </dependencies>

    <build>

        <plugins>

            <plugin>

                <groupId>org.apache.maven.plugins</groupId>

                <artifactId>maven-compiler-plugin</artifactId>

                <version>3.3</version>

                <configuration>

                    <source>1.8</source>

                    <target>1.8</target>

                </configuration>

            </plugin>

        </plugins>

    </build>

</project>

2.4.3.2 接口提供者(service-api-xml module)

定义接口,这里为了方便,只是写一个基本的方法

package com.lagou.service;

public interface HelloService {

    String sayHello(String name);

}

2.4.3.3 提供者(service-provider-xml module)

1.pom文件

<?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">

    <parent>

        <artifactId>dubbo-base-xml</artifactId>

        <groupId>com.lagou</groupId>

        <version>1.0-SNAPSHOT</version>

    </parent>

    <modelVersion>4.0.0</modelVersion>

    <artifactId>service-provider-xml</artifactId>

    <dependencies>

        <dependency>

            <groupId>com.lagou</groupId>

            <artifactId>service-api</artifactId>

            <version>1.0-SNAPSHOT</version>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo</artifactId>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo-registry-zookeeper</artifactId>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo-registry-nacos</artifactId>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo-rpc-dubbo</artifactId>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo-remoting-netty4</artifactId>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo-serialization-hessian2</artifactId>

        </dependency>

    </dependencies>

</project>

2.service 的实现

package com.lagou.service.impl;

import com.lagou.service.HelloService;

public class HelloServiceImpl implements HelloService {

    public String sayHello(String name) {

        return "hello:"+name;

    }

}

3.启动类

package com.lagou;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

public class ProviderApplication {

    public static void main(String[] args) throws IOException {

        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:dubbo-provider.xml");

        context.start();

        System.in.read();

    }

}

4.配置

<?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="service-provider" ></dubbo:application>

    <!-- 使用zookeeper 注册中心暴露 服务地址 -->

    <dubbo:registry address="zookeeper://127.0.0.1:2181" id="r1" timeout="1000"/>

    <!--用 dubbo 协议在20882 端口暴露服务 -->

    <dubbo:protocol name="dubbo" port="20882"/>

    <!--声明需要暴露的服务接口 -->

    <dubbo:service interface="com.lagou.service.HelloService" ref="helloService"/>

    <!-- 和本地一样实现服务 -->

    <bean id="helloService" class="com.lagou.service.impl.HelloServiceImpl"></bean>

</beans>

2.4.3.4 编写服务消费者

1.pom文件

<?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">

    <parent>

        <artifactId>dubbo-base-xml</artifactId>

        <groupId>com.lagou</groupId>

        <version>1.0-SNAPSHOT</version>

    </parent>

    <modelVersion>4.0.0</modelVersion>

    <artifactId>service-conusumer-xml</artifactId>

    <dependencies>

        <dependency>

            <groupId>com.lagou</groupId>

            <artifactId>service-api</artifactId>

            <version>1.0-SNAPSHOT</version>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo</artifactId>

            <exclusions>

                <exclusion>

                    <groupId>org.apache.dubbo</groupId>

                    <artifactId>dubbo-common</artifactId>

                </exclusion>

            </exclusions>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo-registry-zookeeper</artifactId>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo-registry-nacos</artifactId>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo-rpc-dubbo</artifactId>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo-remoting-netty4</artifactId>

        </dependency>

        <dependency>

            <groupId>org.apache.dubbo</groupId>

            <artifactId>dubbo-serialization-hessian2</artifactId>

        </dependency>

    </dependencies>

</project>

2.service 的实现

package com.lagou.service.impl;

import com.lagou.service.HelloService;

public class HelloServiceMock implements HelloService {

    @Override

    public String sayHello(String name) {

        return "hello mock";

    }

}

3.启动类

package com.lagou.service;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ConsumerApplication {

    public static void main(String[] args) {

        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("dubbo-comsumer.xml");

        classPathXmlApplicationContext.start();

        HelloService helloService = classPathXmlApplicationContext.getBean("helloService", HelloService.class);

        String result = helloService.sayHello("world");

        System.out.println("result="+result);

    }

}

4.配置

<?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="service-consumer" >

        <dubbo:parameter key="qos.enable" value="true"/>

        <dubbo:parameter key="qos.port" value="3333"/>

        <dubbo:parameter key="qos.accept.foreign.ip" value="true"/>

    </dubbo:application>

    <!-- -->

    <dubbo:consumer check="false"/>

    <!-- 使用zookeeper 注册中心暴露发现服务地址 -->

    <dubbo:registry address="zookeeper://127.0.0.1:2181" timeout="2000" />

    <!--  生成远程服务代理,可以和本地 bean一样使用 demoService -->

    <dubbo:reference id="helloService" interface="com.lagou.service.HelloService" timeout="4000" retries="2"/>

</beans>

2.5 Dubbo管理控制台 dubbo-admin

5.1 作用

主要包含:服务管理 、 路由规则、动态配置、服务降级、访问控制、权重调整、负载均衡等管理功能

如我们在开发时,需要知道Zookeeper注册中心都注册了哪些服务,有哪些消费者来消费这些服务。我们可以通过部署一个管理中心来实现。其实管理中心就是一个web应用,原来是war(2.6版本以前)包需要部署到tomcat即可。现在是jar包可以直接通过java命令运行。

5.2 控制台安装步骤

1.从git 上下载项目 https://github.com/apache/dubbo-admin

2.修改项目下的dubbo.properties文件 注意dubbo.registry.address对应的值需要对应当前使用的Zookeeper的ip地址和端口号

• dubbo.registry.address=zookeeper://zk所在机器ip:zk端口

• dubbo.admin.root.password=root

• dubbo.admin.guest.password=guest

3.切换到项目所在的路径 使用mvn 打包 mvn clean package -Dmaven.test.skip=true

4.java 命令运行 java -jar 对应的jar包

5.3 使用控制台

1.访问http://IP:端口

2.输入用户名root,密码root

3.点击菜单查看服务提供者和服务消费者信息

6.Dubbo配置项说明

6.1 dubbo:application

对应 org.apache.dubbo.config.ApplicationConfig, 代表当前应用的信息

name: 当前应用程序的名称,在dubbo-admin中我们也可以看到,这个代表这个应用名称。我们在真正时是时也会根据这个参数来进行聚合应用请求。

owner: 当前应用程序的负责人,可以通过这个负责人找到其相关的应用列表,用于快速定位到责任人。

qosEnable : 是否启动QoS 默认true

qosPort : 启动QoS绑定的端口 默认22222

qosAcceptForeignIp: 是否允许远程访问 默认是false

6.2 dubbo:registry

org.apache.dubbo.config.RegistryConfig, 代表该模块所使用的注册中心。一个模块中的服务可以将其注册到多个注册中心上,也可以注册到一个上。后面再service和reference也会引入这个注册中心。

id : 当当前服务中provider或者consumer中存在多个注册中心时,则使用需要增加该配置。在一些公司,会通过业务线的不同选择不同的注册中心,所以一般都会配置该值。

address : 当前注册中心的访问地址。

protocol : 当前注册中心所使用的协议是什么。也可以直接在 address 中写入,比如使用zookeeper,就可以写成 zookeeper://xx.xx.xx.xx:2181 4. timeout : 当与注册中心不再同一个机房时,大多会把该参数延长。

6.3 dubbo:protocol

org.apache.dubbo.config.ProtocolConfig, 指定服务在进行数据传输所使用的协议。

id : 在大公司,可能因为各个部门技术栈不同,所以可能会选择使用不同的协议进行交互。这里在多个协议使用时,需要指定。

name : 指定协议名称。默认使用 dubbo 。

6.4 dubbo:reference

org.apache.dubbo.config.ReferenceConfig, 消费者的配置,这里只做简单说明,后面会具体讲解。

id : 指定该Bean在注册到Spring中的id。 2. interface: 服务接口名

version : 指定当前服务版本,与服务提供者的版本一致。

registry : 指定所具体使用的注册中心地址。这里面也就是使用上面在 dubbo:registry 中所声明的id。

6.5 dubbo:service

org.apache.dubbo.config.ServiceConfig, 用于指定当前需要对外暴露的服务信息,后面也会具体讲解。和 dubbo:reference 大致相同。

interface : 指定当前需要进行对外暴露的接口是什么。

ref : 具体实现对象的引用,一般我们在生产级别都是使用Spring去进行Bean托管的,所以这里面一般也指的是Spring中的BeanId。

version : 对外暴露的版本号。不同的版本号,消费者在消费的时候只会根据固定的版本号进行消费。

6.6 dubbo:method

org.apache.dubbo.config.MethodConfig, 用于在制定的 dubbo:service 或者 dubbo:reference 中的更具体一个层级,指定具体方法级别在进行RPC操作时候的配置,可以理解为对这上面层级中的配置针对于具体方法的特殊处理。

name : 指定方法名称,用于对这个方法名称的RPC调用进行特殊配置。

async: 是否异步 默认false

6.7 dubbo:service和dubbo:reference详解

这两个在dubbo中是我们最为常用的部分,其中有一些我们必然会接触到的属性。并且这里会讲到一些设置上的使用方案。

mock: 用于在方法调用出现错误时,当做服务降级来统一对外返回结果,后面我们也会对这个方法做更多的介绍。

timeout: 用于指定当前方法或者接口中所有方法的超时时间。我们一般都会根据提供者的时长来具体规定。比如我们在进行第三方服务依赖时可能会对接口的时长做放宽,防止第三方服务不稳定导致服务受损。

check: 用于在启动时,检查生产者是否有该服务。我们一般都会将这个值设置为false,不让其进行检查。因为如果出现模块之间循环引用的话,那么则可能会出现相互依赖,都进行check的话,那么这两个服务永远也启动不起来。

retries: 用于指定当前服务在执行时出现错误或者超时时的重试机制。

注意提供者是否有幂等,否则可能出现数据一致性问题

注意提供者是否有类似缓存机制,如出现大面积错误时,可能因为不停重试导致雪崩

executes: 用于在提供者做配置,来确保最大的并行度。

可能导致集群功能无法充分利用或者堵塞

但是也可以启动部分对应用的保护功能

可以不做配置,结合后面的熔断限流使用

6.8 其它配置 参考官网

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 143,048评论 1 300
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 61,330评论 1 256
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 94,541评论 0 213
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 41,042评论 0 176
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 48,821评论 1 255
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 38,795评论 1 176
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 30,413评论 2 271
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,173评论 0 167
  • 想象着我的养父在大火中拼命挣扎,窒息,最后皮肤化为焦炭。我心中就已经是抑制不住地欢快,这就叫做以其人之道,还治其人...
    爱写小说的胖达阅读 28,994评论 6 229
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 32,525评论 0 213
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,327评论 2 215
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 30,648评论 1 230
  • 白月光回国,霸总把我这个替身辞退。还一脸阴沉的警告我。[不要出现在思思面前, 不然我有一百种方法让你生不如死。]我...
    爱写小说的胖达阅读 24,248评论 0 31
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,142评论 2 214
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 31,521评论 3 204
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,622评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,025评论 0 166
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 33,543评论 2 230
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 33,636评论 2 231

推荐阅读更多精彩内容