技术标签: spring boot spring boot分布式
Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合)。从服务模型的角度来看,Dubbo采用的是一种非常简单的模型,要么是提供方提供服务,要么是消费方消费服务,所以基于这一点可以抽象出服务提供方(Provider)和服务消费方(Consumer)两个角色。
我们来看一下Dubbo 的RPC 调用流程,这里主要涉及到4个模块:
Registry:服务注册,我们一般会采取Zookeeper 作为我们的注册中心
Provider:服务提供者(生产者),提供具体的服务实现
Consumer:消费者,从注册中心中订阅服务
Monitor:监控中心,RPC调用次数和调用时间监控
从上图中我们可以了解到整个RPC 服务调用的过程主要为:
1、生产者发布服务到服务注册中心中
2、消费者在服务注册中心中订阅服务
3、消费者调用已经注册的服务
开发环境主要涉及以下几个方面:
Spring-boot
JDK 8
Dubbo
Zookeeper
项目构建通过: http://start.spring.io/ 快速构建web 项目,具体操作可以参考《Spring-Boot:6分钟掌握SpringBoot开发》。
由于Dubbo 中需要使用到服务注册中心,我们这里将使用Zookeeper 作为服务注册中心,具体安装配置,可以参考《Zookeeper-5分钟快速掌握分布式应用程序协调服》
在基础环境确定好了之后,我们项目的目录结构如下:
上图所示,我们项目主要分为了两个模块,一部分是生产者:spring-boot-dubbo ,一部分是:spring-boot-consumer。
整个项目的结构非常简单,这很符合Spring-Boot 的特性,简单便捷,下面我们开始一步步的剖析整个项目的结构
项目依赖这一块主要使用到了基本的Spring-Boot-Web 依赖,然后我们需要额外引入Dubbo 与Zookeeper的依赖(详细依赖可参考源码,博文底部会有项目Github 地址):
<dependency>
<groupId>io.dubbo.springboot</groupId>
<artifactId>spring-boot-starter-dubbo</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.6</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
由于我们底层使用的是Spring-Boot 进行开发,那么我们就应该善于利用Spring-Boot 给我们带来的优势,因此我们可以直接在Application.properties 文件中配置Dubbo 服务:
## Dubbo 服务提供者配置
spring.dubbo.application.name=provider --服务名称
spring.dubbo.registry.address=zookeeper://127.0.0.1:2181 -- 注册中心地址
spring.dubbo.protocol.name=dubbo -- dubbo 协议
spring.dubbo.protocol.port=20880
spring.dubbo.scan=com.jaycekon.dubbo.service --声明需要暴露的服务接口
如果不采用Spring-Boot 进行自动配置,大家可以参考一下的配置xml 配置:
<?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://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 提供方应用信息 -->
<dubbo:application name="provider" />
<!-- 注册中心服务地址 -->
<dubbo:registry protocol="zookeeper" address="127.0.0.1" check="false" />
<!-- 用dubbo协议-->
<dubbo:protocol name="dubbo" port="-1" dispather="all" check="false" />
<dubbo:provider timeout="10000" threads="10" threadpool="fixed" loadbalance="roundrobin"/>
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="com.jaycekon.dubbo.service" ref="userService"/> </beans>
在服务提供主要包括两部分,一个是暴露服务,一个是服务实现
暴露服务:即我们平常开发中所使用的的接口,这里我们创建一个 UserService 的接口,主要包括一个保存用户的方法。
import com.jaycekon.dubbo.domain.User;
/**
* Created by Jaycekon on 2017/9/19.
*/
public interface UserService {
User saveUser(User user);
}
服务实现:服务实现,与我们平常的服务一样,对接口进行实现,比较特别的是,我们这里需要使用到Dubbo 的 @Service 注解
import com.alibaba.dubbo.config.annotation.Service;
import com.jaycekon.dubbo.domain.User;
import com.jaycekon.dubbo.service.UserService;
/**
* Created by Jaycekon on 2017/9/19.
*/
@Service
public class UserServiceImpl implements UserService {
@Override
public User saveUser(User user) {
user.setId(1);
System.out.println(user.toString());
return user;
}
}
Dubbo 的服务提供端,已经总体开发完成,非常简单,总体的目录结构如下:
消费者的相关依赖,与生产者的依赖一致。
<?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.jaycekon</groupId>
<artifactId>spring-boot-consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-boot-consumer</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Spring Boot Dubbo 依赖 -->
<dependency>
<groupId>io.dubbo.springboot</groupId>
<artifactId>spring-boot-starter-dubbo</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.6</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- mvn spring-boot:run 热部署启动 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>1.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
## 避免和 server 工程端口冲突
server.port=8081
## Dubbo 服务消费者配置
spring.dubbo.application.name=consumer
spring.dubbo.registry.address=zookeeper://127.0.0.1:2181
spring.dubbo.scan=com.jaycekon.dubbo.service
基于Xml 的配置:
<?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://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 提供方应用信息 -->
<dubbo:application name="provider" />
<!-- 注册中心服务地址 -->
<dubbo:registry protocol="zookeeper" address="${dubbo.registry.address}" check="false" />
<!-- 用dubbo协议-->
<dubbo:protocol name="dubbo" port="-1" dispather="all" check="false" />
<dubbo:provider timeout="10000" threads="10" threadpool="fixed" loadbalance="roundrobin"/>
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="com.jaycekon.dubbo.service" ref="userService"/>
</beans>
在这里,如果我们需要调用注册服务中的相关服务,则需要实现相关的接口。
import com.jaycekon.dubbo.domain.User;
/**
* Created by Jaycekon on 2017/9/19.
*/
public interface UserService {
User saveUser(User user);
}
例如,在这里我们需要使用到生产者中的 saveUser(User user) 方法,则需要创建一个接口,然后再调用时,使用 @Reference 注解进行引用:
import com.alibaba.dubbo.config.annotation.Reference;
import com.jaycekon.dubbo.domain.City;
import com.jaycekon.dubbo.domain.User;
import org.springframework.stereotype.Component;
/**
* 城市 Dubbo 服务消费者
* <p>
* Created by Jaycekon on 20/09/2017.
*/
@Component
public class CityDubboConsumerService {
@Reference
CityDubboService cityDubboService;
@Reference
UserService userService;
public void printCity() {
String cityName = "广州";
City city = cityDubboService.findCityByName(cityName);
System.out.println(city.toString());
}
public User saveUser() {
User user = new User();
user.setUsername("jaycekon")
.setPassword("jaycekong824");
return userService.saveUser(user);
}
}
最后,我们需要实现一个RESTful 接口,提供给用户调用:
import com.jaycekon.dubbo.service.CityDubboConsumerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by Jaycekon on 2017/9/19.
*/
@RestController
public class UserController {
@Autowired
private CityDubboConsumerService service;
@RequestMapping("/save")
public Object saveUser() {
return service.saveUser();
}
}
本篇博客主要是博主在学习Spring-boot 的时候,总结下来的。在经过一些列的对比后,感觉Dubbo 与Spring-Cloud 还是有点差距的,不管是从服务提供,还是社区活跃来说,Spring-Cloud 还是会强一点。但是由于公司内部使用的是Dubbo,因此还是需要学习一下,后续的话,会对Spring-Cloud 进行学习以及分项。
本文中出现的代码,大家可以到我的 GitHub :多啦A梦 的传送门-https://github.com/jaycekon/SpringBoot
希望大家不要吝啬自己的Star 和 Fork ,谢谢。
文章浏览阅读3.8k次,点赞9次,收藏28次。直接上一个工作中碰到的问题,另外一个系统开启多线程调用我这边的接口,然后我这边会开启多线程批量查询第三方接口并且返回给调用方。使用的是两三年前别人遗留下来的方法,放到线上后发现确实是可以正常取到结果,但是一旦调用,CPU占用就直接100%(部署环境是win server服务器)。因此查看了下相关的老代码并使用JProfiler查看发现是在某个while循环的时候有问题。具体项目代码就不贴了,类似于下面这段代码。while(flag) {//your code;}这里的flag._main函数使用while(1)循环cpu占用99
文章浏览阅读347次。idea shift f6 快捷键无效_idea shift +f6快捷键不生效
文章浏览阅读135次。Ecmacript 中没有DOM 和 BOM核心模块Node为JavaScript提供了很多服务器级别,这些API绝大多数都被包装到了一个具名和核心模块中了,例如文件操作的 fs 核心模块 ,http服务构建的http 模块 path 路径操作模块 os 操作系统信息模块// 用来获取机器信息的var os = require('os')// 用来操作路径的var path = require('path')// 获取当前机器的 CPU 信息console.log(os.cpus._node模块中有很多核心模块,以下不属于核心模块,使用时需下载的是
文章浏览阅读10w+次,点赞435次,收藏3.4k次。SPSS 22 下载安装过程7.6 方差分析与回归分析的SPSS实现7.6.1 SPSS软件概述1 SPSS版本与安装2 SPSS界面3 SPSS特点4 SPSS数据7.6.2 SPSS与方差分析1 单因素方差分析2 双因素方差分析7.6.3 SPSS与回归分析SPSS回归分析过程牙膏价格问题的回归分析_化工数学模型数据回归软件
文章浏览阅读7.5k次。如何利用hutool工具包实现邮件发送功能呢?1、首先引入hutool依赖<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.7.19</version></dependency>2、编写邮件发送工具类package com.pc.c..._hutool发送邮件
文章浏览阅读867次,点赞2次,收藏2次。docker安装elasticsearch,elasticsearch-head,kibana,ik分词器安装方式基本有两种,一种是pull的方式,一种是Dockerfile的方式,由于pull的方式pull下来后还需配置许多东西且不便于复用,个人比较喜欢使用Dockerfile的方式所有docker支持的镜像基本都在https://hub.docker.com/docker的官网上能找到合..._docker安装kibana连接elasticsearch并且elasticsearch有密码
文章浏览阅读1.3w次,点赞57次,收藏92次。整理 | 郑丽媛出品 | CSDN(ID:CSDNnews)近年来,随着机器学习的兴起,有一门编程语言逐渐变得火热——Python。得益于其针对机器学习提供了大量开源框架和第三方模块,内置..._beeware
文章浏览阅读7.9k次。//// ViewController.swift// Day_10_Timer//// Created by dongqiangfei on 2018/10/15.// Copyright 2018年 飞飞. All rights reserved.//import UIKitclass ViewController: UIViewController { ..._swift timer 暂停
文章浏览阅读986次,点赞2次,收藏2次。1.硬性等待让当前线程暂停执行,应用场景:代码执行速度太快了,但是UI元素没有立马加载出来,造成两者不同步,这时候就可以让代码等待一下,再去执行找元素的动作线程休眠,强制等待 Thread.sleep(long mills)package com.example.demo;import org.junit.jupiter.api.Test;import org.openqa.selenium.By;import org.openqa.selenium.firefox.Firefox.._元素三大等待
文章浏览阅读3k次,点赞4次,收藏14次。Java软件工程师职位分析_java岗位分析
文章浏览阅读2k次。Java:Unreachable code的解决方法_java unreachable code
文章浏览阅读1w次。1、html中设置标签data-*的值 标题 11111 222222、点击获取当前标签的data-url的值$('dd').on('click', function() { var urlVal = $(this).data('ur_如何根据data-*属性获取对应的标签对象