week19_day03_Dubbo

服务端高并发分布式架构演进之路


项目经理(leader)
产品经理:制作产品的原型图,给定需求。
UI:画图
前端:前台的流程控制,跳转逻辑,页面效果。
后端:开发功能上实现的一些逻辑。
测试:测试你开发的功能。


什么是分布式?什么是集群?
广义上的分布式就包括昨天讲的Nginx,一个Nginx代理多个服务器。以及微服务。
狭义上的分布式指的就是微服务:每个服务都是由一个单独的应用来提供,服务与服务之间进行轻量级通信,这个通信的框架就叫Dubbo。
在这里插入图片描述
之前所有服务都在同一个应用中的时候,每个服务都在同一个jvm进程中,我们用Spring完成bean的控制。如果在订单模块想使用用户模块的信息,直接通过@Autowired注入,因为他们都在同一个Spring容器中。

现在将一个应用拆分成了几个不同的服务,不同的服务(不同的进程)进行通信,需要使用网络通信。
之前的前后端分离时,前段项目和后段项目之间的通信协议是http协议。


Dubbo支持这些协议:
在这里插入图片描述

大多使用的是Dubbo协议,Dubbo是一个传输层协议。

Dubbo解决了这些进程(服务)之间的跨进程调用问题。但是像链路追踪、分布式事务这些,Dubbo并没有解决这些问题。
而springcloud把一整套的微服务的解决方案都给你了。

Dubbo默认使用的是Dubbo协议(传输层协议)
SpringCloud使用的是http协议(应用层协议)

Dubbo协议调用起来要比http协议快的:因为应用层的数据要到传输层是要拆包的,会有时间损耗的。
在这里插入图片描述


下面讲一下spring和Dubbo的整合:
代码见E:\WangDao\Code7\day1_dubbo\spring-dubbo
目录结构:
在这里插入图片描述

配置:
provider中的application-context.xml:在这里插入图片描述
consumer中的application-context.xml:
在这里插入图片描述

consumer中需要有一个和provider一模一样的接口(包名+类名一模一样)(DemoService),这样consumer才能访问到provider中的DemoService。
DemoService:

package com.cskaoyan.demo;

public interface DemoService {

    String getDetail(String name);
}

consumer并没有真正的写一个DemoServiceImp,而是调用provider的DemoServiceImp来供自己使用。
DemoServiceImp:

package com.cskaoyan.demo.impl;

import com.cskaoyan.demo.DemoService;

/**
 * @author: jia.xue
 * @Email: xuejia@cskaoyan.onaliyun.com
 * @Description
 **/
public class DemoServiceImpl implements DemoService {


    public String getDetail(String name) {

        System.out.println("收到name:" + name);
        return name + ":刘师傅真胖!";
    }
}

所以在启动consumer之前应当先启动provider。
否则会有这样的报错信息:failed to connect to server /127.0.0.1:20880, error message is:Connection refused

我们写代码的时候可能会遇到这种报错信息:No such any registry to export service in provider 192.168.45.1 use dubbo version 2.5.3, Please add <dubbo:registry address="…" /> to your spring config.If you want unregister, please set <dubbo:service registry=“N/A” />
在这里插入图片描述
这幅图是从Dubbo官网下载下来的:provider向外暴露接口的时候,可以将接口暴露到Registry(注册中心)中,也可以暴露给consumer,直接暴露给consumer需要增加一个配置:<dubbo:service registry="N/A" />

在这里插入图片描述
这个实例对象,其实不是真正的DemoServiceImpl对象,而是一个代理对象。
代理对象是一个DemoService 的实例,这个代理对象里面有什么东西呢?
这个代理对象里面放的是 真正提供服务的对象的url地址

Provider:

package com.cskaoyan.demo;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

/**
 * @author: jia.xue
 * @Email: xuejia@cskaoyan.onaliyun.com
 * @Description
 **/
public class Provider {

    public static void main(String[] args) {

        // applicationContext 这个是什么? 这个就是Spring容器对象

        //No such any registry to export service in provider 192.168.45.1 use dubbo version 2.5.3, Please add <dubbo:registry address="..." /> to your spring config.
        // If you want unregister, please set <dubbo:service registry="N/A" />
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application-context.xml");

        // 启动容器
        applicationContext.start();

        System.out.println("启动成功。。。");

        //保持让容器处于启动的状态
        try {
            // 系统阻塞等待输入
            System.in.read();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Consumer:

package com.cskaoyan.demo;

import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @author: jia.xue
 * @Email: xuejia@cskaoyan.onaliyun.com
 * @Description
 **/
public class Consumer {

    public static void main(String[] args) {

        // 初始化consumer容器
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application-context.xml");

        //启动
        applicationContext.start();

        // 从容器里面去取一个bean——"demoService"

        //failed to connect to server /127.0.0.1:20880, error message is:Connection refused


        //这个实例对象,其实不是真正的DemoServiceImpl对象,而是一个代理对象

        // 代理对象是一个DemoService 的实例,这个代理对象里面有什么东西呢?
        // 这个代理对象里面放的是 真正提供服务的对象的url地址
        DemoService demoService = (DemoService) applicationContext.getBean("demoService");


        // 一旦我们去使用代理对象调用方法,那么他就会调用这个代理对象里面封装的url地址的对象的方法
        String response = demoService.getDetail("松哥冲冲冲!");

        // 代理对象(dubbo://127.0.0.1:20880).getDetail ---网络-->   访问 服务提供者的真正的对象实例
        System.out.println(response);
    }
}

先启动Provider在启动Consumer,Consumer就会调用Provider中的接口。


下面讲一下springboot和Dubbo的整合:

  1. 导包
    provider2:
    在这里插入图片描述

dubbo 2.6.0和2.7.1的整合是有一些区别的。我们现在先用2.6.0

和spring整合的dubbo相比,主要区别在于配置
配置:
provider2中的application.properties:
在这里插入图片描述
DemoServiceImpl:
在这里插入图片描述
其中@Service注解是来自:import com.alibaba.dubbo.config.annotation.Service;

@Component表示注入到容器中,相当于下面的bean标签
@Service(interfaceClass = DemoService.class)表示下面的配置接口及其具体实现。

对比provider中的application-context.xml:在这里插入图片描述


consumer2中的application.properties:
在这里插入图片描述
在ThirdService中调用DemoService,在成员变量demoService上写注解
ThirdService相当于工具人,
在这里插入图片描述
对比consumer中的application-context.xml:
在这里插入图片描述


注意:在springboot项目中,如果想启动dubbo,不管provider还是consumer,必须在启动类上加注解:@EnableDubboConfiguration

在这里插入图片描述
ProviderApplication:

package com.cskaoyan.sb.provider;

import com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.io.IOException;

@SpringBootApplication
@EnableDubboConfiguration  // 启动Dubbo服务
public class ProviderApplication {

	public static void main(String[] args) {
		SpringApplication.run(ProviderApplication.class, args);
		try {
			System.in.read();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

ConsumerApplication:

package com.cskaoyan.sb.consumer;

import com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
@EnableDubboConfiguration  // 启动Dubbo服务
public class ConsumerApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext applicationContext = SpringApplication.run(ConsumerApplication.class, args);
        applicationContext.start();

        ThirdService thirdService = applicationContext.getBean(ThirdService.class);

        String response = thirdService.say("ligenli daqi");

        System.out.println(response);

    }

}


注意:url我们都是写死的,一旦provider暴露的端口号变了,consumer就无法从provider中获取信息了。

还记得registry(注册中心)么?
注册中心就是用来做两个服务之间的协调工作的。我们现在使用的注册中心叫zookeeper。

zookeeper是一个分布式协调中间件,类似于Tomcat、mysql、redis等,需要单独启动。

  1. provider2、consumer2导包
    在这里插入图片描述
  2. 将provider2中的application.properties文件稍作修改,开启注册中心
    在这里插入图片描述

同时将consumer2中的application.properties修改:
在这里插入图片描述
3. 这句代码也不需要了
在这里插入图片描述


以上都是基于dubbo2.6版本的,接下来我们写基于dubbo2.7版本的。

在dubbo-demo2这个Module下新建3个Module:provider3、consumer3、common。
其中common下存放provider3和consumer3中共同的部分(DemoService)。

  1. common
    common的pom文件中导入依赖,同时将其打包为jar包,让common作为jar包让provider3和consumer3去依赖。

  2. 在provider3和consumer3中将common这个jar包引入,common里面的依赖provider3和consumer3都能依赖,这就是依赖传递。
    同时provider3和consumer3中都有了common中写的代码。
    provider3和consumer3的pom:
    在这里插入图片描述
    同时启动类中的这个注解不用写了
    在这里插入图片描述
    配置包扫描路径:
    provider3:
    在这里插入图片描述
    consumer3:
    在这里插入图片描述
    provider和consumer中导包:
    在这里插入图片描述
    下面两个包都是为上面的zookeeper服务的。

启动测试即可。
启动顺序:zookeeper、provider、consumer
启动的时候一定要看启动日志是否打印出来,打印出来的话才表示启动成功了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-玫瑰少年-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值