基于Dubbo的跨主机容器通信遇到的问题

前言


最近在项目中使用到DockerDubbo,想在Docker中运行一个服务并把该服务自身的信息发布到Dubbo注册中心。

刚开始测试时候将所有容器都放在同一台主机中,测试过程很顺利,但是当进行Docker主机扩展,将容器部署在不同的主机时候,就发现一个奇怪的现象:应用之间调试不通了。

这里对具体问题解释一下:Dubbo提供了一个方便的服务发现机制,每个服务(这里称为提供者)只要向Dubbo注册中心注册过,注册中心就会将服务的地址发送给同样在注册中心注册的服务调用方(这里称为消费者),之后即使Dubbo注册中心挂了也不影响服务的调用。

当服务提供者部署在容器中时,这时候发现其在Dubbo中心注册的是容器的IP地址,而对于另外一台主机上的消费者来说这个IP是不可访问的,当时我在网上找了很多相关的资料,最后得出几种解决方案。

解决方案


  1. 设置容器的IP与主机IP在同一网段内,使容器IP可直接访问(会占用大量的IP地址,且IP会限制在同一网段,在生产环境中往往不可能)。

  2. 通过复杂的iptables路由规则,通过多层桥接方式打通网络(此法是可行的,也是今后要考虑的,但是操作起来略麻烦)。

  3. 对Dubbo进行扩展,扩展dubbo protocol配置,增加配置项publish host、 publish port,对应主机的ip和port,并且在注册服务时将主机的ip和port写到注册中心。(这种方法需要对Dubbo进行扩展,不太建议)

由一个C++单例模式引出的易错点

基于模板的单例模式


在用C++实现一个单例模式里,发现在调试程序的时候获取到的不是同一个实例,原来代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//Singelton.h
//使用模板实现一个多线程安全的单例模式
#ifndef SINGELTON_H
#define SINGELTON_H
#include <iostream>
#include <mutex>
using namespace std;
mutex mtx;
class Lock
{
private:
mutex *mtx;
public:
explicit Lock(mutex *mtx) :mtx(mtx)
{
this->mtx->lock();
}
~Lock()
{
this->mtx->unlock();
}
};

基于Dubbo的分布式服务

Dubbo简介


Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。

简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候,才有dubbo这样的分布式服务框架的需求,并且本质上是个服务调用的东西,其实就是个远程服务调用的分布式框架(告别Web Service模式中的WSdl,以服务者与消费者的方式在dubbo上注册并调用)。

其核心部分包含:

  1. 远程通讯
    提供对多种基于长连接的NIO框架抽象封装,包括多种线程模型,序列化,以及“请求-响应”模式的信息交换方式。
  2. 集群容错
    提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。
  3. 自动发现
    基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器

计算机系统漫游

从开机说起


当我们按下计算机的电源开关时候,计算机首先会自动从主板的BIOS(基本输入输出系统)读取其中存储的程序。

它引导各个组件如内存、显卡开始运行,允许你从软盘、光盘或者硬盘中选择一个来启动计算机,之后将控制权移交给正常启动的主操作系统。

首先BIOS将从你所选择的存储设备中读取起始的512bytes(比如光盘一开始的512 bytes,如果我们从光盘启动的话)。这512 bytes叫做主引导记录MBR (master boot record)。MBR会告诉电脑从该设备的某一个分区(partition)来装载引导加载程序(boot loader)。Boot loader储存有操作系统(OS)的相关信息,比如操作系统名称,操作系统内核 (kernel)所在位置等。常用的boot loader有GRUBLILO

随后,boot loader会帮助我们加载kernel。kernel实际上是一个用来操作计算机的程序,它是计算机操作系统的内核,主要的任务是管理计算机的硬件资源,充当软件和硬件的接口。操作系统上的任何操作都要通过kernel传达给硬件。Windows和Linux各自有自己kernel。狭义的操作系统就是指kernel,广义的操作系统包括kernel以及kernel之上的各种应用。

深入了解单例模式

最简单的实现


在GoF的23种设计模式中,单例模式是比较简单的一种。

所谓的单例模式,就是在整个应用中保证只有一个类的实例存在。例如一些线程池和数据库连接池都要求是单实例的。

一种最简单的实现就是把类的构造函数写成private的,从而保证别的类不能实例化此类,然后在类中提供一个静态的实例并能够返回给使用者。

1
2
3
4
5
6
7
8
9
10
11
12
13
public class SingletonClass {
private static final SingletonClass instance = new SingletonClass();
public static SingletonClass getInstance(){
return instance;
}
private SingletonClass(){
}
}
Fork me on GitHub