Dubbo
Apache Dubbo是一个高可用的,基于java的开源RPC框架#
不仅包含RPC访问功能,还包含服务治理功能
由阿里巴巴建立,最后由apache维护至今,所以我们选择由apache维护的dubbo
官方地址:https://mvnrepository.com/artifact/org.apache.dubbo/dubbo
常用版本2.7.3
Dubbo架构#
Dubbo支持的协议#
Dubbo协议(官方推荐)#
采用NIO复用单一长连接,使用线程池并发处理请求,减少握手和加大并发效率
大文件上传时,可能出现问题(不适用Dubbo文件上传)
RMI协议(Remote Method Invocation)#
优点:JDK自带的能力
缺点:偶尔连接失败
Hessian协议#
优点:可以与原生Hessian互操作,基于HTTP协议
缺点:需hessian.jar支持,http短连接的开销大
Dubbo支持的注册中心#
Zookeeper(官方推荐)#
优点:支持分布式,周边产品
缺点:受限于Zookeeper软件的稳定性,Zookeeper专门分布式辅助软件,稳定较优
Multicast#
优点:去中心化,不需要单独安装
缺点:Provider和Consumer和Registry不能跨机房(只能在局域网内使用)
Redis#
优点:支持集群,性能高
缺点:要求服务器时间同步,否则可能出现集群失败问题
Simple#
优点:标准RPC服务,没有兼容问题
缺点:不支持集群
第一个Dubbo的Provider#
Dubbo目录结构
创建父工程,添加依赖
<parent> <group>org.springframework.boot</group> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.10.RELEASE</version> </parent>
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.4.2</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.4.2</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.1.10 RELEASE</version> </dependency> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.7.3</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>4.2.0</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>4.2.0</version> </dependency> </dependencyManagement>
DubboService接口
public interface DubboService{ public String service(String param); }
接口实现
@Service public class DubboServiceImpl implements DubboService{ @Reference private dubboService DubboService; @Override public String service(String param){ return DubboService.service("dubbo"); } }
启动类
@SpringBootApplication @EnableDubbo public class ProviderApplication{ public static void main(String[] args){ SpringApplication.run(ProviderApplication.class, args); } }
控制器
public class DubboController{ @Autowired private DubboService dubboService; @RequestMapping("/dubboservice") @RequestBody public String service(){ return dubboService.service(); } }
provider中的application.yml
dubbo:
application:
name: dubbo-provider
registry:
address: zookeeper://192.168.0.1:2181
protocol:
port: 20884
consumer中的application.yml
dubbo:
application:
name: dubbo-consumer
registry:
address: zookeeper://192.168.0.1:2181
protocol:
port: 20884
Admin管理界面搭建#
负载均衡#
集群:一个内容,部署多次,形成的整体称为集群,每个个体应该部署到不同的服务器
伪集群:集群中内容部署到同一台服务器上,通过不同端口区分不同个体
负载均衡是在集群前提下,当访问整个集群时,集群中每个节点都被访问次数或频率的规则
Dubbo内置了四个负载均衡策略,默认为Random
内置策略#
- Random,随机,随机访问集群中结点,访问概率和权重有关
- RoundRobin,轮询,访问频率和权重有关;权重,占有比例,集群中每个项目部署的服务器性能可能不同,性能好的权重高
- LeastActive,活跃数相同的随机,不同的活跃数高的放前面
- ConsistentHash,一致性Hash,相同参数请求总是发到一个提供者
Provider集群#
新建四个启动类
每次启动启动类修改配置文件dubbo.protocal.port
设置负载均衡#
调用的服务采用负载均衡
@Reference(loadbalance = "roundrobin") private DubboService dubboService;
当前拂去采用的负载均衡算法
@Service(loadbalance = "random") public class DubboServiceImpl implements DubboService{}
设置权重
@Service(weight = 4)
配置文件#
dubbo:
application:
name: dubbo-provider
registry:
address: zookeeper://192.168.32.128:2181
protocol:
port: 20884
结构图
pojo.Dept.java
public class Dept implements Serializable{ private Integer id; private String name; // getter setter }
pojo.Emp.java
public class Emp implements Serializable{ private Integer id; private String name; private Stgring phote; private Integer did; // getter setter }
持久层myBatis
application-mybatis.yml
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/test
username: root
password: root
mybatis:
mapper-locations: classpath:mybatis/*.xml
type-aliases-package: com.test.pojo
mapper.DeptMapper
mapper.EmpMapper
provider启动类
@SpringBootApplication @EnableDubbo @MapperScan(com.test.mapper) public class ProviderApplication{ public static void main(String[] args){ SpringApplication.run(ProviderApplication.class, args); } }
provider的applicaton.yml
dubbo:
application:
name: dubbo-provider
registry:
address: zookeeper://192.168.0.1:2181
# 加载其它配置文件, 加载其它的application-*.yml文件
# 多个名称之间用 "," 分隔
spring:
profiles:
active: mybatis
dept子项目的创建
DeptMapper.xml
<mapper namespace="com.test.mapper.DeptMapper"> <select id="findAll" resultType="com.test.pojo.Dept"> select id, name from dept; </select> </mapper>
DeptDubboService
public interface DeptDubboService{ public List<Dept> findAllDept(); }
DeptMapper
public interface DeptMapper{ public List<Dept> findAll(); }
DeptDubboServiceImpl
// 选择Dubbo注解 @Service public class DeptDuboServiceImpl implements DeptDubboService(){ @Autowired private DeptMapper deptMapper; @Override public List<Dept> findAllDept(){ return deptMapper.findAll(); } }
DeptService
public interface DeptService{ public List<Dept> findAll(); public List<Emp> findEmpByDeptId(Integer did); }
DeptServiceImpl
public class DeptServiceImpl implements DeptService{ @Reference private DeptDubboService deptDubboService; @Override public List<Dept> findAll(){ return null; } }
DeptController
@Controller public class DeptController{ @Autowired private DeptService deptService; @GetMapping("/dept") public String showDept(Model model){ model.setAttribute("list", deptService.findAll()); return "dept"; } }
启动类
@SpringBootApplication @EnableDubbo @MapperScan("com.test.mapper") public class ProviderApplication{ public static void main(String[] args){ SpringApplication.run(ProviderApplication.class, args); } }
emp下的application.yml
dubbo:
application:
name: dubbo-emp-consumer
registry:
address: zookeeper://192.168.0.1
server:
port: 8081
EmpApplication
@SpringBootApplication @EnableDubbo public class EmpApplication{ public static void main(String[] args){ SpringApplication.run(EmpApplication.class, args); } }
EmpDubboService
public interface EmpDubboService{ public int insertEmp(Emp emp); public List<Emp> findEmpByDeptId(Integer did); }
EmpDubboServiceImpl
public class EmpDubboServiceImpl implements EmpDubboService{ @Autowired private EmpMapper empMapper; @Override public int insertEmp(Emp emp){ return empMapper.insertEmp(emp); } }
EmpMapper.xml
<mapper namespace="com.test.mapper.EmpMapper" > <insert id="insertEmp" parameterType="com.test.pojo.Emp"> insert into emp(name, photo, did) values(#{name}, #{photo}, #{did}) </insert>
<select id="findEmpByDeptId" parameterType="int" resultType="com.test.pojo.Emp">
select id, name, photo from emp where did = #(did)
</select> </mapper>
EmpService
public interface EmpService{ public List<Dept> showAll(); public int insert(Emp emp, MultipartFile file); }
EmpDubboServiceImpl
public class EmpDubboServiceImpl implements EmpService{ // Dubbo 的 Reference @Reference private DeptDubboService deptDubboService; @Reference private EmpDubboService empDubboService; @Override public List<Dept> showAll(){ return deptDubboService.findAllDept(); } @Override public int insert(Emp emp, MultipartFile file){ try{ // 通过spring容器获取HttpServletRequeest对象 HttpServletRequeest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest(); // 通过HttpServletRequest对象获取图片上传的路径 String path = request.getServletContext().getRealPath("/img"); System.out.println("path == " + path); // 为上传到服务器中的图片的名称不重复, 编写随机数 long currentTimeMills = System.currentTimeMillis(); Random random = new Random(); String fileName = currentTimeMills + "" + random.nextInt(1000); String oldName = file.getOriginalFilename(); fileName += oldName.substring(oldName.lastIndexOf(".")); File pathFile = new File(path); // 第一次上传图片, 检查目录是否存在, 如果不存在, 创建响应目录 if(!pathFile.exist()){ pathFile.mkdirs(); } // 图片上传 file.transferTo(new File(path, fileName)); // 封装emp对象, 把图片路径封装到emp对象中 emp.setPhoto("http://localhost:8081/img/" + fileName); return empDubboService.insertEmp(emp); }catch(IOException e){ e.printStackTrace(); } return 0; } }
EmpController
public class EmpController{ @Autowired private EmpService empService; @GetMapping("/empadd") public String empAdd(Model model){ model.addAttribute("list", empService.showAll()); return "emp-add"; } @PostMapping("/add") public String add(Emp emp, MultipartFile file){ empService.insert(emp, file); return "emp-add"; } }
DeptController
@Controller public class DeptController{ @Autowired private DeptService deptService; @GetMapping("/dept") public String showDept(Model model){ model.addAttribute("list", deptService.findAll()); return "dept"; } @GetMapping("/showEmp") public String showEmp(Integer did, Model model){ model.addAttribute("list", deptService.findEmpByDeptId(did)); return "showEmp"; } }
作者:BigBender
出处:https://www.cnblogs.com/BigBender/p/14360552.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2020-02-03 古典概型和几何概型
2020-02-03 事件的关系与运算
2020-02-03 样本空间和随机事件