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>

效果截图

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/20020.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetcode:寻找数组的中心下标

寻找数组的中心下标 easy 给你一个整数数组 nums &#xff0c;请计算数组的 中心下标 。 数组 中心下标 是数组的一个下标&#xff0c;其左侧所有元素相加的和等于右侧所有元素相加的和。 如果中心下标位于数组最左端&#xff0c;那么左侧数之和视为 0 &#xff0c;因为在下标…

Keil软件激活

首先下载好Keil.rar压缩包 然后关闭本机自带的杀毒软件 然后解压rar压缩包 假定Keil软件已经安装好&#xff0c;这里我就不详述Keil软件的安装过程了 以管理员身份打开Keil软件 打开Keil软件后 &#xff0c;点击如图所示位置 License Management 进入解压之后的文件夹&#x…

LLM InternLM-Chat-7B书生模型、Baichuan-13B-Chat百川模型简单使用

指定GPU运行&#xff1a; #方式一 &#xff08;两行必须放在import torch前面&#xff09; #import os # os.environ[CUDA_VISIBLE_DEVICES] 5#方式二&#xff08;第一种不生效用这种&#xff0c;我这边这种可以生效&#xff09; #import torch #torch.cuda.set_device(5)1、…

设计模式之模板方法实现抽奖功能

1.项目背景 接到一个需求&#xff0c;实现电商营销模块的圆盘抽奖功能。如果大家有关注市面上的抽奖&#xff0c;大致也是圆盘抽奖、九宫格抽奖&#xff0c;随机抽球等等。尤其是电商行业&#xff0c;会有各种各样的活动&#xff0c;因此也会出现各式各样的抽奖&#xff0c;那…

Eclipse控制台输出log4j日志乱码解决

1. 出现乱码可能是编码格式对应不起来&#xff0c;主要是Eclipse控制台编码和log4j编码的匹配 log4j.properties 主要是查看这两个地方编码一致不一致&#xff0c;如果不一致则手动更改成一致编码&#xff0c;GBK或UTF-8

2023年9月广州/重庆/长沙/深圳DAMA-CDGA/CDGP认证考试报名

据DAMA中国官方网站消息&#xff0c;2023年度第三期DAMA中国CDGA和CDGP认证考试定于2023年9月23日举行。 报名通道现已开启&#xff0c;相关事宜通知如下&#xff1a; 考试科目: 数据治理工程师(CertifiedDataGovernanceAssociate,CDGA) 数据治理专家(CertifiedDataGovernanc…

基于单片机的智能温控风扇的设计与实现

功能介绍 以STM32单片机作为主控系统&#xff1b; 液晶显示当前温度&#xff0c;风速等级&#xff0c;自动手动模式息&#xff1b; DS18B20检测当前的温度&#xff1b; 按键设置温度上限&#xff1b; 手动模式下&#xff1a; 直接控制风扇档位&#xff0c;可以开启/关闭风扇&a…

【ubuntu重装系统后的软件配置_memo】

重装系统后系统环境恢复 备份安装系统常用的一些debvscode 更改sourcespip加速爬长城的家伙式儿安装ROS安装cmake安装git安装zsh顺便开个ssh提升幸福感的映射配置neovimplugins字体插件遇到的问题 锁键盘/鼠标小玩意儿 备份 实验时不起眼的图顺手写的脚本忘记从哪儿下载的资源…

计算机网关原理、子网掩码原理(路由器、交换机)(网关:与以太网接口关联的路由)

文章目录 网关网关的历史网关的功能网关的原理相关疑问为什么用子网掩码与IP地址进行与运算来确定一个IP地址所属的子网&#xff1f;网关地址是谁定的&#xff0c;是配置路由的人随意定的吗&#xff1f;&#xff08;配置人员定的&#xff09;如何正确设置网关地址&#xff08;路…

【SAP UI5 控件学习】DAY03 Input组Part III

1. Input 控件 1.1 最简单的Input控件 在UI5框架中&#xff0c;最简单的Input控件也提供了输入提示功能。当用户输入内容的时候&#xff0c;会自动匹配Input控件中所绑定的JSON模型中是数据。 Input的默认匹配规则是匹配从头匹配每一个单词 前端代码如下&#xff1a; <mv…

中值滤波的运用

需求&#xff1a; c#、WPF开发&#xff0c;在界面上画不规则的图形区域&#xff0c;并提取区域内的point 实现方式&#xff1a; 1. 用 InkCanvas控件作为画布&#xff0c;用path画不规则图形 2. 将InkCanvas控件内的内容保存为jpg图片 3. 通过判断区域的颜色&#xff0c;从而得…

ARP协议(地址分析协议)

系列文章目录 数通王国历险记&#xff08;4&#xff09; 目录 前言 一&#xff0c;什么是地址解析协议&#xff08;ARP&#xff09; 二&#xff0c;封装和解封装 三&#xff0c;为什么需要地址解析协议&#xff08;ARP&#xff09; 四&#xff0c;ARP的验证实验 4.1&#x…