Dubbo分布式服务框架,springboot+dubbo+zookeeper
一Dubbo的简易介绍
1.Dubbo是什么?
Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。
简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候,才有dubbo这样的分布式服务框架的需求,并且本质上是个服务调用的东西,说白了就是个远程服务调用的分布式框架(告别Web Service模式中的WSdl,以服务者与消费者的方式在dubbo上注册)。
其核心部分包含:
1. 远程通讯:
提供对多种基于长连接的NIO框架抽象封装,包括多种线程模型,序列化,以及“请求-响应”模式的信息交换方式。
2. 集群容错:
提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。
3. 自动发现
基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。
2.Dubbo能做什么?
1.透明化的远程方法调用
就像调用本地方法一样调用远程方法,只需简单配置,没有任何API侵入。
2.软负载均衡及容错机制
可在内网替代F5等硬件负载均衡器,降低成本,减少单点。
3. 服务自动注册与发现
不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址,并且能够平滑添加或删除服务提供者。
Dubbo采用全spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载。
3.Dubbo核心组件

1)注册中心(registry)
生产者在此注册并发布内容,消费者在此订阅并接收发布的内容。
2)消费者(consumer)
客户端,从注册中心获取到方法,可以调用生产者中的方法。
3)生产者(provider)
服务端,生产内容,生产前需要依赖容器(先启动容器)。
4)容器(container)
生产者在启动执行的时候,必须依赖容器才能正常启动(默认依赖的是spring容器),
5)监控(Monitor)
统计服务的调用次数与时间等。
二.springboot+dubbo+zookeeper整合使用
1.在Linux中安装zookeeper实现服务注册

进入到镜像中
[root ~]# docker exec -it 46c8d188683b bash
查看zookeeper中的,服务情况

查看已经注册存在的服务

2.服务层中service,使用dubbo中的@Service注解

3.Providor服务提供者

3.0.application.yml
dubbo:provider:application: dubbo-providerregistry:address: zookeeper://192.168.58.128:2181scan:base-packages:- com.tjetc.serviceprotocol:name: dubbo #使用dubbo协议port: 20880 #协议端口为20880
server:port: 8081
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://192.168.58.128:3306/springboot?serverTimezone=GMT%2B8username: rootpassword: root
mybatis:type-aliases-package: com.tjetc.domain
logging:level:com.tjetc.mapper: debug
3.1.ProvidorApplication
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
//开启dubbo服务注册
("com.tjetc.mapper")
public class ProvidorApplication {public static void main(String[] args) {SpringApplication.run(ProvidorApplication.class, args);}}
3.2.ProductServiceImpl,@Service使用dubbo中的注解
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tjetc.domain.Product;
import com.tjetc.mapper.ProductMapper;
import com.tjetc.service.ProductService;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.util.List;
public class ProductServiceImpl implements ProductService {private ProductMapper productMapper;public void add(Product product) {productMapper.add(product);}public PageInfo<Product> list(String name, Integer pageNum, Integer pageSize) {PageHelper.startPage(pageNum,pageSize);List<Product> list=productMapper.list(name);PageInfo<Product> pageInfo = new PageInfo<>(list);System.out.println("pageInfo.getList() = " + pageInfo.getList());return pageInfo;}public List<Product> listByName(String name) {return productMapper.listByName(name);}public Product findById(Integer id) {return productMapper.findById(id);}public void update(Product product) {productMapper.update(product);}public int del(Integer id) {return productMapper.del(id);}
}
4.mapper模块,代码省略

5.实体类对象模块domain,代码省略

6.Service服务接口,代码省略

7.consumer,服务消费者

7.0.ComsumerApplication

7.1.ProductController
import com.alibaba.dubbo.config.annotation.Reference;
import com.github.pagehelper.PageInfo;
import com.tjetc.domain.Product;
import com.tjetc.service.ProductService;
import com.tjetc.utils.FastDfsClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.util.List;
("/product")
public class ProductController {("${fastdfs}")private String fastdfs;private ProductService productService;("/add")public String add(){return "add";}("/add")public String add(Product product, MultipartFile photo){System.out.println("photo = " + photo);System.out.println("product = " + product);if (photo!=null && photo.getSize()>0){String filename = photo.getOriginalFilename();String extName = filename.substring(filename.lastIndexOf(".")+1);FastDfsClient fastDfsClient = new FastDfsClient("classpath:client.properties");try {//7. 显示上传的结果(file_id 也就是文件的路径)String path = fastDfsClient.upload(photo.getBytes(), extName);System.out.println("path = " + path);product.setPhotopath(fastdfs+path);} catch (IOException e) {e.printStackTrace();}}System.out.println("product = " + product);productService.add(product);return "redirect:/product/list";}("/list")public String list((defaultValue = "") String name,(defaultValue = "1") Integer pageNum,(defaultValue = "3") Integer pageSize, Model model){System.out.println(productService);PageInfo<Product> pageInfo=productService.list(name,pageNum,pageSize);List<Product> list = pageInfo.getList();for (Product product : list) {System.out.println("product = " + product);}/*List<Product> list = productService.listByName(name);System.out.println("list = " + list);*/model.addAttribute("page",pageInfo);model.addAttribute("list",list);model.addAttribute("name",name);return "list";}("/findById")public String findById(Integer id,Model model){Product product=productService.findById(id);model.addAttribute("p",product);return "update";}("/update")public String update(Product product,MultipartFile photo){if (photo!=null && photo.getSize()>0){String fileName=photo.getOriginalFilename();String extName=fileName.substring(fileName.lastIndexOf(".")+1);FastDfsClient fastDfsClient = new FastDfsClient("classpath:client.properties");try {String path = fastDfsClient.upload(photo.getBytes(), extName);product.setPhotopath(fastdfs+path);} catch (IOException e) {e.printStackTrace();}}productService.update(product);return "redirect:/product/list";}("/del")public String del(Integer id){int i=productService.del(id);return "redirect:/product/list";}}
7.2.FastDfsClient集合文件系统工具类
import org.csource.common.MyException;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;/*** FastDFS上传文件的工具类*/
public class FastDfsClient {//声明4个成员变量private TrackerClient trackerClient=null;private TrackerServer trackerServer=null;// 4. 声明存储服务端storageprivate StorageServer storageServer=null;private StorageClient1 storageClient=null;/** 根据配置文件初始化4个成员变量* */public FastDfsClient(String config) {Properties properties = new Properties();if (config.contains("classpath:")) {try {config=config.replaceAll("classpath:","");System.out.println("config = " + config);// 使用ClassLoader加载properties配置文件生成对应的输入流InputStream in = this.getClass().getClassLoader().getResourceAsStream(config);// 使用properties对象加载输入流properties.load(in);System.out.println("properties = " + properties);// 1. 加载配置文件ClientGlobal.initByProperties(properties);} catch (IOException e) {e.printStackTrace();} catch (MyException e) {e.printStackTrace();}}else {try {ClientGlobal.initByProperties(config);} catch (IOException e) {e.printStackTrace();} catch (MyException e) {e.printStackTrace();}}// 2. 创建tracker的客户端this.trackerClient = new TrackerClient();try {// 3. 通过客户端得到服务端连接对象this.trackerServer = trackerClient.getConnection();} catch (IOException e) {e.printStackTrace();}// 5. 获取存储服务器的storage客户端对象this.storageClient = new StorageClient1(trackerServer, storageServer);}public FastDfsClient() {}public String upload(String filename, String extName, NameValuePair[] metas){try {return storageClient.upload_file1(filename, extName, metas);} catch (IOException e) {e.printStackTrace();} catch (MyException e) {e.printStackTrace();}return null;}public String upload(String filename,String exName){return this.upload(filename, exName,null);}/*** *根据文件的内容上传** @paramcontent文件内容byte[]** @paramextName文件扩展名* *@parammetas参数*@return*/public String upload(byte[] content,String extNAme,NameValuePair[] metas){try {return storageClient.upload_file1(content, extNAme, metas);} catch (IOException e) {e.printStackTrace();} catch (MyException e) {e.printStackTrace();}return null;}public String upload(byte[] content,String extName){return this.upload(content, extName,null);}public static void main(String[] args) {// 外部普通类System.out.println("方法名 类名");System.out.println("getName " + FastDfsClient.class.getName());System.out.println("getCanonicalName " + FastDfsClient.class.getCanonicalName());System.out.println("getSimpleName " + FastDfsClient.class.getSimpleName());System.out.println();//用代码实现:得到类路径的真实路径String path = FastDfsClient.class.getClassLoader().getResource("").getPath();System.out.println("path = " + path);}}
7.3.client.properties
fastdfs.tracker_servers=192.168.58.128:22122
7.4.application.yml
fastdfs: http://192.168.58.128/
dubbo:application:name: dubbo-consumerregistry:address: zookeeper://192.168.58.128:2181protocol:name: dubbo #使用dubbo协议port: 20880 #协议端口为20880server:port: 8082
spring:servlet:multipart:# 设置 上传文件的大小max-file-size: 20MB# 设置 整个请求的大小max-request-size: 20MB
7.5.list.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title><style type="text/css">table{width: 700px;border-collapse: collapse;text-align: center;}th,td{border: 1px solid #CCCCCC;}</style><script type="text/javascript">function fenye(pageNum) {alert(document.getElementById("pageSize").value)location.href="/product/list?pageNum="+pageNum+"&name="+document.getElementById("name").value;}function findById(id) {location.href="/product/findById?id="+id;}function del(id) {location.href="/product/del?id="+id;}</script>
</head>
<body>
<div><input type="text" id="name" th:value="${name}" placeholder="请输入商品名称"><button th:onclick="fenye(1)">查询</button>
</div>
<table><tr><th>编号</th><th>名称</th><th>单价</th><th>时间</th><th>美照</th><th>操作</th></tr><tr th:each="p:${list}"><td th:text="${p.id}"></td><td th:text="${p.name}"></td><td th:text="${p.price}"></td><td th:text="${#dates.format(p.time)}"></td><td><img th:src="${p.photopath}" width="100px"></td><td><button th:onclick="|findById(${p.id})|">编辑</button><button th:onclick="|del(${p.id})|">删除</button></td></tr><tr><td colspan="10"><button th:onclick="|fenye(1)|">首页</button><button th:onclick="|fenye(${page.prePage})|">上一页</button>当前页<span th:text="${page.pageNum}"></span>/<span th:text="${page.pages}"></span><button th:onclick="|fenye(${page.nextPage})|">下一页</button><button th:onclick="|fenye(${page.pages})|">尾页</button>每页<select id="pageSize" th:onclick="fenye(1)"><option value="3">3</option><option value="6">6</option><option value="9">9</option></select>条数据总记录数:<span th:text="${page.total}"></span></td></tr>
</table>
</body>
</html>
效果截图



相关文章:
Dubbo分布式服务框架,springboot+dubbo+zookeeper
一Dubbo的简易介绍 1.Dubbo是什么? Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。 简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需…...
网络:UDP out of order;SIP;CPU out-of-order 执行
文章目录 问题SIP如果使用UDP出现乱序网络CPU问题 最近遇到虚拟机收到的UDP包发生乱序。从协议上说,这个乱序是标准,及特性所允许的,期望的。所以上层应用需要适应这种乱序,如果不能适应,可能需要做协议转换,专用TCP,让TCP来处理这种乱序的可能。 产生乱序的原因: 是网…...
我心中的TOP1编程语言—JavaScript
作为一名研发工程师(程序员),平时工作中肯定会接触或了解很多编程语言。每个人都会有自己工作中常用的语言,也会有偏爱的一些编程语言。而我心中的最爱,毫无疑问,就是 JavaScript。 JavaScript 是一门编程…...
CentOS环境下的Maven安装
CentOS 安装 Maven 镜像地址 镜像地址:https://mirrors.tuna.tsinghua.edu.cn/apache/maven/ 下载地址:https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.8.8/binaries/ 下载maven 将下载好的压缩包拷贝到根目录下 解压 tar -zxvf ap…...
表的增删改查
1、创建表 mysql> create table employee ( -> id int(1) comment 员工编号, -> name varchar(6) comment 员工名字, -> gender varchar(2) comment 员工性别, -> salary int (4) comment 员工薪资); Query OK, 0 rows affected (0.01 sec) 2、…...
Tauri 应用中发送 http 请求
最近基于 Tauri 和 React 开发一个用于 http/https 接口测试的工具 Get Tools,其中使用了 tauri 提供的 fetch API,在开发调试过程中遇到了一些权限和参数问题,在此记录下来。 权限配置 在 tauri 应用中,如果想要使用 http 或 fe…...
基于霍夫变换的航迹起始算法研究(Matlab代码实现)
目录 💥1 概述 📚2 运行结果 🎉3 参考文献 👨💻4 Matlab代码 💥1 概述 一、设计内容 利用Hough变换处理量测得到的含杂波的二维坐标,解决多目标航迹起始问题。使用Matlab进行仿真&#x…...
如何使用Excel公式将(d:1,a:4,c:2,b:3)快速分割成8列并按顺序排列
Excel是一款功能强大的电子表格软件,可以帮助我们处理各种数据。在处理数据时,有时候需要将一列数据按照特定的格式进行分割和重新排列。本文将介绍如何使用Excel公式将"(d:1,a:4,c:2,b:3)"快速分割成8列,并按照指定顺序排列为&quo…...
遥控泊车系统技术规范
目 录 1. 版本履历... 3 2. 文档使用范围... 3 3. 术语缩写... 3 4. 系统架构... 4 5. 功能需求... 4 5.1 功能清单... 4 6.2 功能关系描述(如有)... 4 5.3 功能1. 4 5.3.1 功能总体状态动态说…...
qt 线程状态机实现并发自动任务
一、状态机类 头文件 MyStateMachine.h#ifndef MYSTATEMACHINE_H #define MYSTATEMACHINE_H#include <QStateMachine> #include "ActionTask.h" #include...
社交机器人培育
论文: 自我繁殖的假新闻:机器人和人工智能使印度冲突地区的社会两极分化永久化 Self-Breeding Fake News: Bots and Artificial Intelligence Perpetuate Social Polarization in India’s Conflict Zones 论文链接:https://jps.library.ut…...
CUnit在ARM平台上的离线搭建(让CUnit编译安装成功之后的可执行文件.so变成ARM下的—ARM aarch64)(实用篇)
前言:1 CUint-2.1-3.tar.bz2压缩安装包下载并解压2 进入CUint-2.1-3目录并且通过指令./bootstrap*产生configure *执行文件3 执行./configure*命令4 make编译5 make install 安装 前言: 在X86架构上的Linux操作系统上面进行cmake编译(Cyclon…...
整数序列(山东大学考研机试题)
水仙花数(中南考研机试题) 链接:3644. 水仙花数 - AcWing题库 /* 暴力枚举罢了 */ #include<iostream> using namespace std; const int N1e3100; int book[N]; int pow3(int k){return k*k*k; } int main() {int m,n;for(int i100;i<999;i){int t1,t2,t3;t1 i%10;t…...
k8s集群安装
目录 一 主机准备 1.1 设备配置 ⚠️注意1 ⚠️注意2 1.2 环境准备 1.3docker安装 二 安装kubeadm、kubectl、kubelet 2.1 添加镜像源 2.2 安装 三 master节点部署 四 node节点加入集群 五 CNI网络插件calico 六 其他节点使用kubectl 1.拷贝文件 2.添加到环境变量…...
【webrtc】ProcessThreadAttached
RegisterModule 调用所在的线程指针传递给ProcessThreadAttached ProcessThreadAttached 调用不是在worker thread 而是在 registers/deregister 这个module或者 start stop 这个module的时候 ** ** pacedsender是一个moudle -实现了...
Orange pi3初调试
因为树莓派沦为理财产品1年前出手殆尽后,现在唯一一个B性能不足一直没动力调试,沦为吃灰工具。 偶然之间多多给推了个orange产品预售,看了下pi3的参数,这不和赚了差价的3B一个性能吗?果断定了个预售款,在差…...
手机里的视频怎么转换成MP4格式?简单的转换方法分享
MP4格式是一种广泛使用的视频格式,几乎所有设备和操作系统都支持MP4格式的视频播放。无论是使用 iPhone、iPad、安卓手机、电视等各种设备,都可以播放 MP4 格式的视频。这种广泛的兼容性使得 MP4 成为一种非常方便的视频格式,我们可以随时随地…...
Matlab数学建模实战——(Lokta-Volterra掠食者-猎物方程)
1.题目 问题1 该数学建模的第一问和第二问主要是用Matlab求解微分方程组,直接编程即可。 求解 Step1改写 y(1)ry(2)f Step2得y的导数 y(1).2y(1)-ay(1)*y(2)y(2).-y(2)a*y(1)*y(2) Step3编程 clear; a0.01; F(t,y)[2*y(1)-a*y(1)*y(2);-y(2)a*y(1)*y(2)]; […...
windows下软件推荐
起源与目的 选择任何一个系统作为主力系统都是要好好考虑的。 在去年新买了一块1T的SSD后,就好好想了想这个问题。 Arch Linux, Ubuntu, Windows, macOS, deepin都是在考虑范围的。 不过我考虑到使用体验,最终还是选择了windows。 不选择macOS主要是不喜…...
SQlite数据库
SQlite数据库 1.SQLite简介 轻量化,易用的嵌入式数据库,用于设备端的数据管理,可以理解成单点的数据库。传统服务器型数据库用于管理多端设备,更加复杂 SQLite是一个无服务器的数据库,是自包含的。这也称为嵌入式数…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...
CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...
Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...
【WebSocket】SpringBoot项目中使用WebSocket
1. 导入坐标 如果springboot父工程没有加入websocket的起步依赖,添加它的坐标的时候需要带上版本号。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dep…...
解析“道作为序位生成器”的核心原理
解析“道作为序位生成器”的核心原理 以下完整展开道函数的零点调控机制,重点解析"道作为序位生成器"的核心原理与实现框架: 一、道函数的零点调控机制 1. 道作为序位生成器 道在认知坐标系$(x_{\text{物}}, y_{\text{意}}, z_{\text{文}}…...
