一、了解分布式应用
什么是分布式应用?在谈谈这个之前我们先说一下与它对立的就是集中式应用,集中式应用就是在一个应用中包含了所有的应用资源,这样做有很大的坏处,项目会变得更繁重,维护麻烦,而且不便于二次开发。为了解决这些问题,就出现了分布式应用。
1.分布式应用程序:
分布式应用程序是指应用程序分布在不同计算机上,通过网络来共同完成一项任务。通常为服务器/客户端模式。
服务器/客户端又分为二端(server/client)、三端(server/middleware/client)、N端(multiple server/multiple minddle/multiple client),看看下面几张图会更加清楚的认识:
RPC的原理:
RPC技术的底层原理:就是对象的序列化、反序列化以及序列化后数据的传输,dubbo(使用二进制文件,TCP)。
二、什么是Dubbo
dubbo是什么:
dubbo是一个阿里巴巴开发的开源分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,是阿里巴巴集团的各成员站点的核心框架,每天为2,000+个服务提供3,000,000,000+次访问量支持。
为什么要用dubbo:
应用场景:
当网站变大后,不可避免的需要拆分应用进行服务化,以提高开发效率,调优性能,节省关键竞争资源等。
当服务越来越多时,服务的URL地址信息就会爆炸式增长,配置管理变得非常困难,F5硬件负载均衡器的单点压力也越来越大。
当进一步发展,服务间依赖关系变得错踪复杂,甚至分不清哪个应用要在哪个应用之前启动,架构师都不能完整的描述应用的架构关系。
接着,服务的调用量越来越大,服务的容量问题就暴露出来,这个服务需要多少机器支撑?什么时候该加机器?等等……
在遇到这些问题时,都可以用Dubbo来解决。
dubbo的优势:
1、使用简单
2、部署轻盈
3、方便二次开发
当当网:dubboX
京东:jd-hydra
dubbo核心组成部分分析:
其核心部分包含:
1. 远程通讯: 提供对多种基于长连接的NIO框架抽象封装,包括多种线程模型,序列化,以及“请求-响应”模式的信息交换方式。
2. 集群容错: 提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。
3. 自动发现: 基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。
三、注册中心概述
注册中心的作用:
1、服务端服务的注册和客户端服务的调用
2、提高系统的可用性
3、提高系统的可伸缩性
4、集中管理服务
注册中心有什么:
multicast:
组播(multicast): 也叫多播, 多点广播或群播。 指把信息同时传递给一组目的地址。它使用策略是最高效的,因为消息在每条网络链路上只需传递一次,而且只有在链路分叉的时候,消息才会被复制。
(ps:我们的计算机除了组播还有什么呢:单播和广播)
224.0.0.0~224.0.0.255为预留的组播地址(永久组地址),地址224.0.0.0保留不做分配,其它地址供路由协议使用;
zookeeper:
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。
四、搭建第一个分布式应用程序【HelloWorld】
hello world开发步骤:
1,创建三个项目
一个用于服务端,一个用于客户端,一个用于接口
服务端:dubbo-demo-server
客户端:dubbo-demo-client
接口:dubbo-demo-api
三个项目的关系图如下:
首先在主项目中导入pom依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.3</version>
</dependency>
2.编写接口代码
接口:dubbo-demo-api代码:
HelloWorldService.java
package cn.just.service;
import org.dubbo.demo.api.HelloWorld;
public interface HelloWorldService {
public HelloWorld helloworld(HelloWorld helloWorld);
}
HelloWorld.java
package org.dubbo.demo.api;
import java.io.Serializable;
public class HelloWorld implements Serializable{ //注意rpc是通过socket对消息进行序列化和反序列化的发送和接受处理的,所以必须实现Serializable,否则会报错
public String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
3.导入依赖包
将接口(dubbo-demo-api)打成jar包,然后导入服务端和客户端程序中
4.编写服务端程序
HelloWorldServiceImpl.java:
package cn.just.service.impl;
import org.dubbo.demo.api.HelloWorld;
import cn.just.service.HelloWorldService;
public class HelloWorldServiceImpl implements HelloWorldService{
//业务处理
@Override
public HelloWorld helloworld(HelloWorld hello) {
hello.setName("shinelon");
return hello;
}
}
主程序APP.java:
package org.dubbo.demo.server;
import java.io.IOException;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.ServiceConfig;
import cn.just.service.HelloWorldService;
import cn.just.service.impl.HelloWorldServiceImpl;
/**
* Hello world!
*
*/
public class App {
HelloWorldServiceImpl helloWorldService=new HelloWorldServiceImpl();
private void helloworld() {
//当前应用配置
ApplicationConfig applicationConfig = new ApplicationConfig();
//当前应用名(不能用空格)
applicationConfig.setName("helloWorld");
//注册中心配置
RegistryConfig registryConfig = new RegistryConfig();
//设置注册中心地址
registryConfig.setAddress("multicast://224.5.6.7:1234");
//registryConfig.set
//服务提供者协议配置
ProtocolConfig protocolConfig = new ProtocolConfig();
//协议名
protocolConfig.setName("dubbo");
//协议端口
protocolConfig.setPort(20880);
//服务配置
ServiceConfig<HelloWorldService> serviceConfig = new ServiceConfig<HelloWorldService>();
//设置当前应用配置
serviceConfig.setApplication(applicationConfig);
//设置注册中心
serviceConfig.setRegistry(registryConfig);
//设置协议配置
serviceConfig.setProtocol(protocolConfig);
//添加服务的接口字节码
serviceConfig.setInterface("cn.just.service.HelloWorldService");
//添加服务接口的具体实现类
serviceConfig.setRef(helloWorldService);
//把服务发布出去
serviceConfig.export();
System.out.println("服务启动");
try {
System.in.read();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main( String[] args )
{
// System.out.println( "Hello World!" );
new App().helloworld();
}
}
5,发布服务
启动服务端程序
6,编写客户端调用程序
App.java:
package org.dubbo.demo.client;
import org.dubbo.demo.api.HelloWorld;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ReferenceConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import cn.just.service.HelloWorldService;
/**
* Hello world!
*
*/
public class App {
private void helloworld() {
//应用配置
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("helloWorldConsumer");
//连接注册中心
RegistryConfig registryConfig = new RegistryConfig();
//设置注册中心地址
registryConfig.setAddress("multicast://224.5.6.7:1234");
//引用远程服务地址
ReferenceConfig<HelloWorldService> referenceConfig = new ReferenceConfig<HelloWorldService>();
referenceConfig.setApplication(applicationConfig);
referenceConfig.setRegistry(registryConfig);
referenceConfig.setInterface("cn.just.service.HelloWorldService");
//和本地一样调用服务
HelloWorldService helloWorldService = referenceConfig.get();
HelloWorld helloWorld=new HelloWorld();
helloWorld=helloWorldService.helloworld(helloWorld);
System.out.println("=======================");
System.out.println(helloWorld.getName());
}
public static void main( String[] args )
{
new App().helloworld();
}
}
7.启动客户端进行调用
此时我们会发现应用调用成功。至此我们已经搭建好我么第一次dubbo分布式应用程序,下面是整个项目的目录结构截图:
需要源码的朋友可前往下载:
https://github.com/ljcan/Dubbo
本人能力有限,上述有什么不足之处还望不吝赐教。