首页> 标签> Dubbo
"Dubbo"
共 2940 条结果
全部 问答 文章 公开课 课程 电子书 技术圈 体验
SpringCloud Hoxton——初探 & Eureka服务注册与发现
1.开篇我们都知道,之前有一套微服务叫做Dubbo+Zookeeper,Dubbo是一个RPC框架,是阿里巴巴的,但是后来阿里停止了对Dubbo的维护,并把Dubbo共享给了Apache,在这个节骨眼上,SpringCloud趁虚而入,于是,在微服务的领域火了起来。SpringCloud官网:https://spring.io/projects/spring-cloudSpringCloud的版本关系:Spring Cloud 采用了英国伦敦地铁站的名称来命名,并由地铁站名称字母A-Z依次类推的形式来发布迭代版本。SpringCloud是一个由许多子项目组成的综合项目,各子项目有不同的发布节奏。为了管理SpringCloud与各子项目的版本依赖关系,发布了一个清单,其中包括了某个SpringCloud版本对应的子项目版本。为了避免SpringCloud版本号与子项目版本号混淆,SpringCloud版本采用了名称而非版本号的命名,这些版本的名字采用了伦敦地铁站的名字,根据字母表的顺序来对应版本时间顺序。例如Angel是第一个版本, Brixton是第二个版本。当SpringCloud的发布内容积累到临界点或者一个重大BUG被解决后,会发布一个"service releases"版本,简称SRX版本,比如Greenwich.SR2就是SpringCloud发布的Greenwich版本的第2个SRX版本。下面这张图是SpringCloud和SpringBoot之间的版本关系。这里,我跟随尚硅谷的教学视频,学习的是SpringCloud Hoxton和SpringCloud alibaba。项目中的版本约定如下:SpringCloud Hoxton:SR1SpringCloud alibaba:2.1.0.RELEASESpringBoot:2.2.2.RELEASEJava:jdk1.8Maven:3.5及以上MySQL:5.7及以上2.项目源码构建github源码地址:https://github.com/2656307671/SpringCloud-Hoxton-Eureka-gitee源码地址:https://gitee.com/szh-forever-young/spring-cloud-hoxton-eureka这个微服务支付模块下面一共搭建了6个子模块。(Eureka集群的服务注册与发现)1.    公共实体类子模块cloud-api-commons2.    Eureka Server端服务注册中心cloud-eureka-server7001(类似于教育部)3.    Eureka Server端服务注册中心cloud-eureka-server7002(同7001)4.    Eureka Client端服务提供者cloud-provider-payment8001(类似于北京大学,需要在教育部注册即可教学,注册完成即可对外提供招生等服务)5.    Eureka Client端服务提供者cloud-provider-payment8002(类似于清华大学,需要在教育部注册即可教学,注册完成即可对外提供招生等服务)6.    Eureka Client端服务消费者cloud-consumer-order80(类似于清华北大的学生,可以在服务提供者各大学中进行消费)这6个子模块的构建步骤无非就是这几步:建module、改pom、写yml、主启动类、业务类、测试。创建完一个模块之后,最好使用maven中的install命令,将该工程发布到仓库,以便其他工程使用。测试的时候,一定要实现热部署。6个子模块的启动顺序:2、3、4、5、6测试结果如下:(分别是7001、7002两个注册中心的首页,以及服务消费者的访问)
文章
SpringCloudAlibaba  ·  Dubbo  ·  Java  ·  关系型数据库  ·  MySQL  ·  应用服务中间件  ·  Apache  ·  Maven  ·  微服务  ·  Spring
2022-06-17
Dubbo——使用Zookeeper注册中心实现Dubbo
1.写在前面有关Zookeeper注册中心的相关内容,可以参考我的这篇博客:https://blog.csdn.net/weixin_43823808/article/details/1173390442.案例分析这里使用注册中心仍然需要三个maven工程,第一个是maven java工程,后两个是maven web工程,创建步骤不再多说了。2.1 第一个是maven java工程这其中提供的是服务模型(实体Bean)、服务接口(对外提供的方法),这个工程不需要添加任何依赖。package com.szh.dubbo.model; import java.io.Serializable; /** * */ public class User implements Serializable { private Integer id; private String username; //getter and setter }package com.szh.dubbo.service; import com.szh.dubbo.model.User; /** * */ public interface UserService { User queryUserById(Integer id,String username); }2.2 第二个是maven web工程这个代表的是服务提供者,其中包含对第一个maven java工程中服务接口方法的实现。package com.szh.dubbo.service.impl; import com.szh.dubbo.model.User; import com.szh.dubbo.service.UserService; /** * */ public class UserServiceImpl implements UserService { @Override public User queryUserById(Integer id, String username) { User user=new User(); user.setId(id); user.setUsername(username); return user; } }dubbo服务提供者的配置文件。之前我们使用的直连方式实现dubbo,所以地址端口号是 dubbo://localhost:20880。现在使用了zookeeper注册中心,这个地址和端口号要做修改:zookeeper://localhost:2181。<?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://dubbo.apache.org/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!-- 声明dubbo服务提供者的名称:保证唯一性 --> <dubbo:application name="007-zk-userservice-provider"/> <!-- 声明dubbo使用的协议和端口号 --> <dubbo:protocol name="dubbo" port="20880"/> <!-- 使用zookeeper注册中心,指定注册中心的地址、端口号 --> <dubbo:registry address="zookeeper://localhost:2181"/> <!-- 暴露接口服务 --> <dubbo:service interface="com.szh.dubbo.service.UserService" ref="userServiceImpl"/> <!-- 加载接口实现类 --> <bean id="userServiceImpl" class="com.szh.dubbo.service.impl.UserServiceImpl"/> </beans>由于在服务提供者中,需要加载之前服务接口的实现类,所以这里需要用到Spring的监听器,同时读取dubbo配置文件。<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:dubbo-zk-userservice-provider.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>pom文件中的相关依赖。 <!-- Spring依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.5.RELEASE</version> </dependency> <!-- SpringMVC依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.5.RELEASE</version> </dependency> <!-- Dubbo依赖 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> </dependency> <!-- 接口工程依赖 --> <dependency> <groupId>com.szh.dubbo</groupId> <artifactId>006-zk-interface</artifactId> <version>1.0.0</version> </dependency> <!-- Zookeeper依赖 --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>4.1.0</version> </dependency>2.3 第三个是maven web工程这个代表的是服务消费者,其中包含一个控制层方法的实现,去响应之前的服务接口。package com.szh.dubbo.controller; import com.szh.dubbo.model.User; import com.szh.dubbo.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; /** * */ @Controller public class UserController { @Autowired private UserService userService; @RequestMapping(value = "/userDetail") public String userDetail(Integer id, String username, Model model) { User user=userService.queryUserById(id,username); model.addAttribute("user",user); return "userDetail"; } }然后是dubbo服务消费者的配置文件、Spring配置文件。<?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://dubbo.apache.org/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!-- 声明dubbo服务消费者名称:保证唯一性 --> <dubbo:application name="008-zk-consumer"/> <!-- 指定注册中心 --> <dubbo:registry address="zookeeper://localhost:2181"/> <!-- 引用远程接口服务 --> <dubbo:reference id="userService" interface="com.szh.dubbo.service.UserService"/> </beans><?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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 声明组件扫描器 --> <context:component-scan base-package="com.szh.dubbo.controller"/> <!-- 开启springmvc注解驱动 --> <mvc:annotation-driven/> <!-- 配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"/> <property name="suffix" value=".jsp"/> </bean> </beans>最后是web.xml和控制层方法对应的jsp页面。<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml,classpath:dubbo-zk-consumer.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app><%@ page contentType="text/html;charset=utf-8" language="java" %> <html> <head> <title>$</title> </head> <body> <h3>用户详情</h3> <div>用户编号:${user.id}</div> <div>用户姓名:${user.username}</div> </body> </html>2.4 启动测试!!!为后两个maven web工程配置各自的tomcat服务器(配置过程在这里就不多说了。。。)。由于之前使用的是直连方式实现dubbo,所以配置完tomcat,先启动dubbo服务提供者的tomcat,再启动dubbo服务消费者的tomcat,直接去浏览器输入url就可以访问了。现在使用了zookeepr注册中心,所以配置完tomcat之后,我们需要到zookeeper的根目录的bin目录下,找到zkServer.cmd先启动注册中心,然后启动dubbo服务提供者的tomcat,再启动dubbo服务消费者的tomcat,再到浏览器输入url就可以访问了。
文章
Dubbo  ·  Java  ·  应用服务中间件  ·  Maven  ·  Spring
2022-06-17
干货|接口测试必备技能-常见接口协议解析
服务与服务之间传递数据包,往往会因为不同的应用场景,使用不同的通讯协议进行传递。比如网站的访问,常常会使用 HTTP 协议进行传递,文件传输使用 FTP,邮件传递使用 SMTP。上述的三种类型的协议都处于网络模型中的应用层。除了应用层的常用协议之外,对于传输层的 TCP、UDP 协议,以及 Restful 架构风格、RPC 协议等等基础网络知识要有一定的了解和认知。网络协议介绍在了解具体的协议之前,需要先了解 OSI 七层模型、TCP/IP 四层模型、五层体系结构这三种不同的网络模型。网络协议模型对比图:1080×451 183 KBOSI 参考模型是一个在制定协调进程间通信标准时所使用的概念性框架,它并不是一个标准。TCP/IP 四层模型是网际网络的基础通信架构。常视为是简化的七层 OSI 模型。五层协议是 OSI 和 TCP/IP 的综合,实际应用还是 TCP/IP 的四层结构。TCP/IP 协议栈是对应 TCP/IP 四层模型所使用的具体的网络协议TCP协议TCP 协议是在传输层中,一种面向连接的、可靠的、基于字节流的传输层通信协议。TCP 协议的工作方式为在建立连接的时候需要进行“三次握手”,终止连接时需要进行“四次挥手”。“三次握手”和“四次挥手”是 TCP 协议的重要知识点,在后面的章节会通过实战和理论结合,具体介绍这一重要的知识点。TCP 协议的面向连接、错误重传、拥塞控制等特性,适用于可靠性高的场景,比如涉及用户信息的数据传输。UDP协议UDP 协议一旦把应用程序发给网络层的数据发送出去,就不保留数据备份。它仅在 IP 数据包的头部加入复用和数据校验字段。所以 UDP 常常被认为是不可靠的数据包协议。UDP 协议的不需要提前建立连接、实现简单的特性,非常适用于实时性高的场景,比如流媒体、在线游戏等。HTTP协议HTTP 协议是接口测试中最常见的协议,用于分布式、协作式和超媒体信息系统的应用层协议。HTTP 是万维网的数据通信的基础。客户端向服务端发送 HTTP 请求,服务端则会在响应中返回所请求的数据。在测试过程中,常常需要校验请求和响应结果,所以了解 HTTP 协议,对于接口测试来说,是重中之重。在后面章节将会具体介绍 HTTP、HTTPS 协议的区别,以及 HTTP 协议的基础知识信息。RESTful架构起源Roy Thomas Fielding 博士于 2000 年在他的博士论文中提出来的一种万维网软件架构风格。其目的是为了便于不同的软件在网络中传递信息。RESTful 是基于 HTTP 协议之上制定的一种资源请求、操作的风格,用一句话来概括就是使用 URL 去定位资源,使用 HTTP 动词描述操作。HTTP 请求方法在 RESTful api 中的典型应用:注意: 不同公司在使用 RESTful 架构风格的时候存在部分差别。RPC协议目前在行业内常用的 RPC 协议主要如下:Dubbo:Java 基础之上的高性能 RPC 协议gRPC:高性能通用 RPC 框架,基于 Protocol BuffersPB 是一个语言中立、平台中立的数据序列化框架。Thrift:与 gRPC 类似的多语言 RPC 框架。常见接口协议解析暂时就讲这些哈,如果大家有其他想了解的知识点也可以在下方留言哦!小编尽量满足大家的需求哈~
文章
自然语言处理  ·  网络协议  ·  Dubbo  ·  Java  ·  应用服务中间件  ·  网络性能优化  ·  API  ·  网络架构
2022-06-17
SpringBoot——借助Maven多模块管理实现集成SSM、Dubbo、Thymeleaf的汇总案例
文章目录:1.写在前面1.1 maven父工程(普通Java工程):管理JDK编译级别、子工程需要用到的依赖1.2 第一个子工程(普通Java工程):对应接口工程1.3 第二个子工程(SpringBoot工程):对应服务提供者1.4 第三个子工程(SpringBoot工程):对应服务消费者2.该案例的所有源码2.1 maven父工程(普通Java工程):管理JDK编译级别、子工程需要用到的依赖2.2 第一个子工程(普通Java工程):对应接口工程2.3 第二个子工程(SpringBoot工程):对应服务提供者2.4 第三个子工程(SpringBoot工程):对应服务消费者2.5 启动测试!!!1.写在前面这个大综合案例,我使用Maven多模块管理来实现,就像之前创建SpringBoot项目一样,它的pom文件中会有一个父工程,而父工程中又会有一个父工程,在这个父工程(通俗的说爷爷工程)中,就是各种各样需要用到的依赖。也就是说,这个案例,先是有一个maven父工程,它是一个SpringBoot工程,它来管理其他模块中需要用到的依赖、以及JDK的编译级别。而这里集成了Dubbo,那么肯定就会有接口工程、服务提供者、服务消费者这三个工程,而这三个工程都会是上面提到的maven父工程的三个子工程。OKOK,说了这么多,下面直接放上这四个maven工程的架构图。1.1 maven父工程(普通Java工程):管理JDK编译级别、子工程需要用到的依赖1.2 第一个子工程(普通Java工程):对应接口工程1.3 第二个子工程(SpringBoot工程):对应服务提供者1.4 第三个子工程(SpringBoot工程):对应服务消费者2.该案例的所有源码2.1 maven父工程(普通Java工程):管理JDK编译级别、子工程需要用到的依赖在这个maven工程中,什么都没有,只有一个pom文件(maven项目的核心!!!) 。因为我写的这个案例是SpringBoot集成XXX,所有我需要代替之前创建SpringBoot工程的那些功能,在这里指定这个maven工程为一个SpringBoot工程(也就是pom文件中 <parent> 标签中的内容),这样我才可以管理JDK编译级别、子工程需要用到的依赖(也就是pom文件中 <properties>、<dependencyManagement>标签中的内容)。而声明该maven工程为父工程需要两个条件:①将 <packaging> 标签的内容设置为pom;②删除该工程的src目录。<?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> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.5.0</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.szh.springboot</groupId> <artifactId>017-springboot-parent</artifactId> <version>1.0.0</version> <packaging>pom</packaging> <properties> <java.version>11</java.version> <dubbo-spring-boot-starter-version>2.0.0</dubbo-spring-boot-starter-version> <zkclient-version>0.4</zkclient-version> <mybatis-spring-boot-starter-version>2.1.4</mybatis-spring-boot-starter-version> </properties> <!-- 管理SpringBoot父工程没有管理的依赖 --> <dependencyManagement> <dependencies> <!-- Dubbo集成SpringBoot框架的起步依赖 --> <dependency> <groupId>com.alibaba.spring.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>${dubbo-spring-boot-starter-version}</version> </dependency> <!-- zookeeper注册中心 --> <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> </exclusions> </dependency> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>${zkclient-version}</version> </dependency> <!-- MyBatis集成SpringBoot框架的起步依赖 --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>${mybatis-spring-boot-starter-version}</version> </dependency> </dependencies> </dependencyManagement> </project>2.2 第一个子工程(普通Java工程):对应接口工程首先来看它的pom文件,这里有一个 <parent> 标签,那么意思就是说它有一个父工程叫:017-springboot-parent<relativePath>../017-springboot-parent/pom.xml</relativePath>的意思是通过相对路径找到父工程的pom文件。<?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> <parent> <artifactId>017-springboot-parent</artifactId> <groupId>com.szh.springboot</groupId> <version>1.0.0</version> <relativePath>../017-springboot-parent/pom.xml</relativePath> </parent> <artifactId>018-springboot-dubbo-ssm-interface</artifactId> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> </properties> </project>因为这是一个接口工程,所有它还需要实体bean(集成Dubbo的实体bean必须实现序列化)和servic业务接口。package com.szh.springboot.entity; import java.io.Serializable; public class Student implements Serializable { private Integer id; private String name; private Integer age; //getter and setter }package com.szh.springboot.service; import com.szh.springboot.entity.Student; /** * */ public interface StudentService { Student queryStudentById(Integer id); }2.3 第二个子工程(SpringBoot工程):对应服务提供者首先来看它的pom文件。在 <parent> 标签中指定了它的父工程,这里面就用到了 017 工程中管理的各种依赖,此时我们就不需要再声明版本号了,因为父工程017中已经有了!!!<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <artifactId>017-springboot-parent</artifactId> <groupId>com.szh.springboot</groupId> <version>1.0.0</version> <relativePath>../017-springboot-parent/pom.xml</relativePath> </parent> <artifactId>019-springboot-ssm-dubbo-provider</artifactId> <dependencies> <!-- SpringBoot框架web项目起步依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Dubbo集成SpringBoot框架的起步依赖 --> <dependency> <groupId>com.alibaba.spring.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> </dependency> <!-- zookeeper注册中心 --> <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> </exclusions> </dependency> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> </dependency> <!-- MyBatis集成SpringBoot框架的起步依赖 --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> <!-- MySQL驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- 接口工程 --> <dependency> <groupId>com.szh.springboot</groupId> <artifactId>018-springboot-dubbo-ssm-interface</artifactId> <version>1.0.0</version> </dependency> </dependencies> <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.*</include> </includes> </resource> </resources> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>因为它是一个SpringBoot工程,是一个集成Dubbo之后的服务提供者,所以它还需要dao、mapper、对接口工程中接口方法的实现。package com.szh.springboot.mapper; import com.szh.springboot.entity.Student; public interface StudentMapper { Student selectByPrimaryKey(Integer id); }<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.szh.springboot.mapper.StudentMapper"> <resultMap id="BaseResultMap" type="com.szh.springboot.entity.Student"> <id column="id" jdbcType="INTEGER" property="id" /> <result column="name" jdbcType="VARCHAR" property="name" /> <result column="age" jdbcType="INTEGER" property="age" /> </resultMap> <sql id="Base_Column_List"> id, name, age </sql> <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap"> select <include refid="Base_Column_List" /> from t_student where id = #{id,jdbcType=INTEGER} </select> </mapper>package com.szh.springboot.service.impl; import com.alibaba.dubbo.config.annotation.Service; import com.szh.springboot.entity.Student; import com.szh.springboot.mapper.StudentMapper; import com.szh.springboot.service.StudentService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * */ @Component @Service(interfaceClass = StudentService.class,version = "1.0.0",timeout = 15000) public class StudentServiceImpl implements StudentService { @Autowired private StudentMapper studentMapper; @Override public Student queryStudentById(Integer id) { return studentMapper.selectByPrimaryKey(id); } }同时配置SpringBoot的核心配置文件。 # 配置内嵌tomcat端口号和上下文根 server.port=8081 server.servlet.context-path=/ # 配置连接数据库的信息 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8 spring.datasource.username=root spring.datasource.password=12345678 # 配置Dubbo spring.application.name=019-springboot-ssm-dubbo-provider spring.dubbo.server=true spring.dubbo.registry=zookeeper://localhost:2181最后是SpringBoot项目启动入口类。package com.szh.springboot; import com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @MapperScan(basePackages = "com.szh.springboot.mapper") @EnableDubboConfiguration public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }2.4 第三个子工程(SpringBoot工程):对应服务消费者首先来看它的pom文件。 在 <parent> 标签中指定了它的父工程。<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <artifactId>017-springboot-parent</artifactId> <groupId>com.szh.springboot</groupId> <version>1.0.0</version> <relativePath>../017-springboot-parent/pom.xml</relativePath> </parent> <artifactId>020-springboot-ssm-dubbo-consumer</artifactId> <dependencies> <!-- SpringBoot框架集成Thymeleaf前端模板引擎的起步依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- SpringBoot框架web项目的起步依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Dubbo集成SpringBoot框架的起步依赖 --> <dependency> <groupId>com.alibaba.spring.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> </dependency> <!-- zookeeper注册中心 --> <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> </exclusions> </dependency> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> </dependency> <!-- 接口工程 --> <dependency> <groupId>com.szh.springboot</groupId> <artifactId>018-springboot-dubbo-ssm-interface</artifactId> <version>1.0.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>因为它是一个SpringBoot工程,是一个集成Dubbo之后的服务消费者,所以它还需要一个控制层方法的实现,以及响应的html页面。package com.szh.springboot.controller; import com.alibaba.dubbo.config.annotation.Reference; import com.szh.springboot.entity.Student; import com.szh.springboot.service.StudentService; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; /** * */ @Controller public class StudentController { @Reference(interfaceClass = StudentService.class,version = "1.0.0",check = false) private StudentService studentService; @RequestMapping(value = "/student/detail/{id}") public String studentDetail(@PathVariable("id") Integer id, Model model) { Student student=studentService.queryStudentById(id); model.addAttribute("student",student); return "studentDetail"; } }<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>学生详情</h3> 学生编号:<span th:text="${student.id}"></span><br/> 学生姓名:<span th:text="${student.name}"></span><br/> 学生年龄:<span th:text="${student.age}"></span><br/> </body> </html>最后是SpringBoot的核心配置文件,以及SpringBoot项目启动入口类。# 配置内嵌tomcat的端口号和上下文根 server.port=8080 server.servlet.context-path=/ # 关闭Thymeleaf的页面缓存开关 spring.thymeleaf.cache=false # 配置Thymeleaf前后缀 spring.thymeleaf.prefix=classpath:/templates/ spring.thymeleaf.suffix=.html # 配置字符编码格式 server.servlet.encoding.enabled=true server.servlet.encoding.force=true server.servlet.encoding.charset=UTF-8 # 配置Dubbo spring.application.name=020-springboot-ssm-dubbo-consumer spring.dubbo.registry=zookeeper://localhost:2181package com.szh.springboot; import com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @EnableDubboConfiguration public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }2.5 启动测试!!!启动的步骤如下:👇👇👇1.    启动zookeeper注册中心(zkServer.cmd),我这里直接就在Windows端启动了。2.    启动服务提供者的Tomcat。3.    启动服务消费者的Tomcat。4.    到浏览器中输入请求方法中定义的 url 访问就可以了。 
文章
Dubbo  ·  Java  ·  应用服务中间件  ·  Maven  ·  Windows
2022-06-17
SpringBoot——SpringBoot集成SSM、Dubbo、Redis、JSP的汇总案例
文章目录:1.思路讲解2.案例分析2.1 接口工程2.2 服务提供者2.3 服务消费者2.4 启动测试!!!1.思路讲解这个案例其实就是SpringBoot集成SSM、Dubbo、Redis、JSP,看起来集成了一大堆,感觉挺麻烦的,但实际上并不是很麻烦,下面我来说一下我的思路:·       接口工程:存放实体bean和业务接口·       服务提供者:它是一个SpringBoot框架web项目,集成MyBatis、Redis              1)pom文件中添加依赖:MyBatis、MySQL驱动、Dubbo、zookeeper、redis、接口工程。              2)配置springboot核心配置文件(连接数据库、连接redis、dubbo、内嵌tomcat)·       服务消费者:它也是一个SpringBoot框架web项目,集成JSP、Dubbo              1)pom文件中添加依赖:Dubbo、zookeeper、接口工程、解析jsp页面的依赖。              2)配置springboot核心配置文件(dubbo、内嵌tomcat、视图解析器)文章比较长,因为代码比较多,大家一定要有这个耐心去看完,相信我讲的还是有点用的!!!2.案例分析这里SpringBoot集成MyBatis,我用的是MyBatis逆向工程来直接生成的实体bean、dao、mapper,所以这里首先给出MyBatis逆向工程的配置文件。这个文件主要是负责生成你项目中的实体bean、dao、mapper,那么再加上集成dubbo的情况下,我们的实体bean是需要放在接口工程中的,而dao、mapper则需要放在服务提供者中,所以在MyBatis逆向工程的配置文件中,需要将实体bean的生成位置改为第一个接口工程的绝对路径。数据库这里的表结构和数据,我就不再给出了,大家自行创建一下就可以了。<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <!-- 指定连接数据库的 JDBC 驱动包所在位置,指定到你本机的完整路径 --> <classPathEntry location="E:\mysql-connector-java-5.1.9.jar"/> <!-- 配置 table 表信息内容体,targetRuntime 指定采用 MyBatis3 的版本 --> <context id="tables" targetRuntime="MyBatis3"> <!-- 抑制生成注释,由于生成的注释都是英文的,可以不让它生成 --> <commentGenerator> <property name="suppressAllComments" value="true"/> </commentGenerator> <!-- 配置数据库连接信息 --> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/springboot" userId="root" password="12345678"> </jdbcConnection> <!-- 生成 entity 类,targetPackage 指定 entity 类的包名, targetProject指定生成的 entity 放在 IDEA 的哪个工程下面--> <javaModelGenerator targetPackage="com.szh.springboot.entity" targetProject="D:\BaiduNetdiskDownload\014-springboot-ssm-dubbo-interface\src\main\java"> <property name="enableSubPackages" value="false"/> <property name="trimStrings" value="false"/> </javaModelGenerator> <!-- 生成 MyBatis 的 Mapper.xml 文件,targetPackage 指定 mapper.xml 文件的包名, targetProject 指定生成的 mapper.xml 放在 IDEA 的哪个工程下面 --> <sqlMapGenerator targetPackage="com.szh.springboot.mapper" targetProject="src/main/java"> <property name="enableSubPackages" value="false"/> </sqlMapGenerator> <!-- 生成 MyBatis 的 Mapper 接口类文件,targetPackage 指定 Mapper 接口类的包名, targetProject 指定生成的 Mapper 接口放在 IDEA 的哪个工程下面 --> <javaClientGenerator type="XMLMAPPER" targetPackage="com.szh.springboot.mapper" targetProject="src/main/java"> <property name="enableSubPackages" value="false"/> </javaClientGenerator> <!-- 数据库表名及对应的 Java 模型类名 --> <table tableName="t_student" domainObjectName="Student" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/> </context> </generatorConfiguration>2.1 接口工程MyBatis逆向工程生成的实体bean。package com.szh.springboot.entity; import java.io.Serializable; public class Student implements Serializable { private Integer id; private String name; private Integer age; //getter and setter }接口服务,其中有两个方法。package com.szh.springboot.service; import com.szh.springboot.entity.Student; /** * */ public interface StudentService { Student queryStudentById(Integer id); Integer queryAllStudentCount(); }2.2 服务提供者SpringBoot核心配置文件# 配置内嵌tomcat端口号和上下文根 server.port=8081 server.servlet.context-path=/ # 设置连接数据库的信息 spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8 spring.datasource.username=root spring.datasource.password=12345678 # 设置dubbo spring.application.name=015-springboot-ssm-dubbo-provider spring.dubbo.server=true spring.dubbo.registry=zookeeper://localhost:2181 # 设置redis spring.redis.host=localhost spring.redis.port=6379MyBatis逆向工程生成的dao接口和对应的mapper映射文件(这里就做一个简单的案例,所以只用到了 selectByPrimaryKey、queryAllStudentCount 这两个方法)package com.szh.springboot.mapper; import com.szh.springboot.entity.Student; public interface StudentMapper { int deleteByPrimaryKey(Integer id); int insert(Student record); int insertSelective(Student record); Student selectByPrimaryKey(Integer id); int updateByPrimaryKeySelective(Student record); int updateByPrimaryKey(Student record); Integer queryAllStudentCount(); }<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.szh.springboot.mapper.StudentMapper"> <resultMap id="BaseResultMap" type="com.szh.springboot.entity.Student"> <id column="id" jdbcType="INTEGER" property="id" /> <result column="name" jdbcType="VARCHAR" property="name" /> <result column="age" jdbcType="INTEGER" property="age" /> </resultMap> <sql id="Base_Column_List"> id, name, age </sql> <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap"> select <include refid="Base_Column_List" /> from t_student where id = #{id,jdbcType=INTEGER} </select> <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer"> delete from t_student where id = #{id,jdbcType=INTEGER} </delete> <insert id="insert" parameterType="com.szh.springboot.entity.Student"> insert into t_student (id, name, age ) values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}, #{age,jdbcType=INTEGER} ) </insert> <insert id="insertSelective" parameterType="com.szh.springboot.entity.Student"> insert into t_student <trim prefix="(" suffix=")" suffixOverrides=","> <if test="id != null"> id, </if> <if test="name != null"> name, </if> <if test="age != null"> age, </if> </trim> <trim prefix="values (" suffix=")" suffixOverrides=","> <if test="id != null"> #{id,jdbcType=INTEGER}, </if> <if test="name != null"> #{name,jdbcType=VARCHAR}, </if> <if test="age != null"> #{age,jdbcType=INTEGER}, </if> </trim> </insert> <update id="updateByPrimaryKeySelective" parameterType="com.szh.springboot.entity.Student"> update t_student <set> <if test="name != null"> name = #{name,jdbcType=VARCHAR}, </if> <if test="age != null"> age = #{age,jdbcType=INTEGER}, </if> </set> where id = #{id,jdbcType=INTEGER} </update> <update id="updateByPrimaryKey" parameterType="com.szh.springboot.entity.Student"> update t_student set name = #{name,jdbcType=VARCHAR}, age = #{age,jdbcType=INTEGER} where id = #{id,jdbcType=INTEGER} </update> <select id="queryAllStudentCount" resultType="java.lang.Integer"> select count(*) from t_student </select> </mapper>对接口工程中接口方法的实现,其中包括注入数据库持久层、注入redis模板类对象。package com.szh.springboot.service.impl; import com.alibaba.dubbo.config.annotation.Service; import com.szh.springboot.entity.Student; import com.szh.springboot.mapper.StudentMapper; import com.szh.springboot.service.StudentService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import java.util.concurrent.TimeUnit; /** * */ @Component @Service(interfaceClass = StudentService.class,version = "1.0.0",timeout = 15000) public class StudentServiceImpl implements StudentService { @Autowired private StudentMapper studentMapper; @Autowired private RedisTemplate<Object,Object> redisTemplate; @Override public Student queryStudentById(Integer id) { return studentMapper.selectByPrimaryKey(id); } @Override public Integer queryAllStudentCount() { //首先去redis缓存中查询,如果有:直接使用;如果没有,去数据库中查询并存放到redis缓存中 Integer allStudentCount= (Integer) redisTemplate.opsForValue().get("allStudentCount"); //判断是否有值 if (allStudentCount==null) { //此时为空,则去数据库中查询 allStudentCount=studentMapper.queryAllStudentCount(); //并存放到redis缓存中 redisTemplate.opsForValue().set("allStudentCount",allStudentCount,30, TimeUnit.SECONDS); } return allStudentCount; } }pom文件 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba.spring.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.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> </exclusions> </dependency> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.4</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.4</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.9</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- 接口工程 --> <dependency> <groupId>com.szh.springboot</groupId> <artifactId>014-springboot-ssm-dubbo-interface</artifactId> <version>1.0.0</version> </dependency> </dependencies> <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> </resources> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <!--mybatis 代码自动生成插件--> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.7</version> <configuration> <!--配置文件的位置--> <configurationFile>GeneratorMapper.xml</configurationFile> <verbose>true</verbose> <overwrite>true</overwrite> </configuration> </plugin> </plugins> </build>SpringBoot项目启动入口类package com.szh.springboot; import com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @MapperScan(basePackages = "com.szh.springboot.mapper") @EnableDubboConfiguration public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }2.3 服务消费者SpringBoot核心配置文件# 配置内嵌tomcat端口号和上下文根 server.port=8080 server.servlet.context-path=/ # 设置dubbo spring.application.name=016-springboot-ssm-dubbo-consumer spring.dubbo.registry=zookeeper://localhost:2181 # 配置视图解析器 spring.mvc.view.prefix=/ spring.mvc.view.suffix=.jsp定义控制层,其中有两个请求方法package com.szh.springboot.controller; import com.alibaba.dubbo.config.annotation.Reference; import com.szh.springboot.entity.Student; import com.szh.springboot.service.StudentService; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; /** * */ @Controller public class StudentController { @Reference(interfaceClass = StudentService.class,version = "1.0.0",check = false) private StudentService studentService; @RequestMapping(value = "/student/detail/{id}") public String studentDetail(@PathVariable("id") Integer id, Model model) { Student student=studentService.queryStudentById(id); model.addAttribute("student",student); return "studentDetail"; } @GetMapping(value = "/student/all/count") public @ResponseBody Object allStudentCount() { Integer allStudentCount=studentService.queryAllStudentCount(); return "学生总人数为:" + allStudentCount; } }pom文件 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba.spring.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.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> </exclusions> </dependency> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.4</version> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> </dependency> <!-- 接口工程 --> <dependency> <groupId>com.szh.springboot</groupId> <artifactId>014-springboot-ssm-dubbo-interface</artifactId> <version>1.0.0</version> </dependency> </dependencies> <build> <resources> <resource> <directory>src/main/webapp</directory> <targetPath>META-INF/resources</targetPath> <includes> <include>*.*</include> </includes> </resource> </resources> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>响应的jsp页面、SpringBoot项目启动入口类<%@ page contentType="text/html;charset=utf-8" language="java" %> <html> <head> <title>$</title> </head> <body> <h3>学生信息</h3> <div>学生编号:${student.id}</div> <div>学生姓名:${student.name}</div> <div>学生年龄:${student.age}</div> </body> </html>package com.szh.springboot; import com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @EnableDubboConfiguration public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }2.4 启动测试!!!因为我们这个案例是SpringBoot集成SSM、Dubbo、Redis、JSP,同时使用注册中心。所以启动的步骤是:1.    启动zookeeper注册中心 zkServer.cmd(我这里为了考虑电脑性能,所以直接就在Windows上启动了,推荐是在Linux上启动)2.    启动redis服务(redis-server.exe redis,windows.conf    、  redis-cli.exe -h 127.0.0.1 -p 6379)3.    启动服务提供者(对应该工程的SpringBoot项目启动入口类)4.    启动服务消费者(对应该工程的SpringBoot项目启动入口类)测试结果中,可以看到,第一个请求结果拿到了学生信息,第二个请求结果也查询出了学生数量,而且我们开启redis服务之后,可以看到发起第二个请求之后,redis缓存中已经有了这个 allStudentCount 数据,经过30秒之后,这个数据会被清除。
文章
NoSQL  ·  Dubbo  ·  Java  ·  关系型数据库  ·  应用服务中间件  ·  数据库连接  ·  Linux  ·  Redis  ·  数据库  ·  mybatis
2022-06-17
SpringBoot——SpringBoot集成Dubbo
1.写在前面这里我来总结一下SpringBoot集成Dubbo的小案例,那么有关Dubbo的内容,就不多说了,可以参考下面这张图中的分栏中的文章。下面,来说一说SpringBoot集成Dubbo分布式框架的一个思路:首先了话,仍然需要三个工程。·       接口工程:存放实体bean和业务接口·       服务提供者:业务接口的实现类,同时将服务暴露,注册到注册中心zookeeper,调用数据持久层(dao)                a. pom文件中添加依赖(dubbo、注册中心zookeeper、接口工程)                b. 配置服务提供者的dubbo核心配置文件。·       服务消费者:处理浏览器客户端发来的请求,从注册中心调用服务提供者所提供的服务。                a. pom文件中添加依赖(dubbo、注册中心zookeeper、接口工程)                b. 配置服务消费者的dubbo核心配置文件。那么,为了简单起步,这里我不再写实体bean了,也不再调用数据持久层了,就做一个简单的模拟案例吧。2.案例分析2.1 接口工程业务接口package com.szh.springboot.service; /** * */ public interface StudentService { Integer queryAllStudentCount(); }2.2 服务提供者SpringBoot核心配置文件# 配置内嵌tomcat的端口号和上下文跟 server.port=8081 server.servlet.context-path=/ # 配置Dubbo # 声明dubbo服务提供者的名称:保证唯一性 spring.application.name=012-springboot-dubbo-provider # 当前工程是一个服务提供者 spring.dubbo.server=true # 设置注册中心的地址端口号 spring.dubbo.registry=zookeeper://localhost:2181对业务接口方法的实现。@Component注解表示将该实现类加载到Spring容器中。@Service注解(这个注解和Spring下的@Service注解不一样,它是dubbo下属的直接)interface指的是暴露接口服务,version是版本号,timeout是超时时间。package com.szh.springboot.service.impl; import com.alibaba.dubbo.config.annotation.Service; import com.szh.springboot.service.StudentService; import org.springframework.stereotype.Component; /** * */ @Component @Service(interfaceClass = StudentService.class,version = "1.0.0",timeout = 15000) public class StudentServiceImpl implements StudentService { @Override public Integer queryAllStudentCount() { return 666; } }pom文件 <!-- SpringBoot框架web项目起步依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Dubbo集成SpringBoot框架的起步依赖 --> <dependency> <groupId>com.alibaba.spring.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency> <!-- 注册中心zookeeper --> <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> </exclusions> </dependency> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.4</version> </dependency> <!-- 接口工程 --> <dependency> <groupId>com.szh.springboot</groupId> <artifactId>011-springboot-dubbo-interface</artifactId> <version>1.0.0</version> </dependency>最后是SpringBoot项目启动入口类package com.szh.springboot; import com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication //开启Spring注解配置 @EnableDubboConfiguration //开启Dubbo注解配置 public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }2.3 服务消费者SpringBoot核心配置文件# 配置内嵌tomcat的端口号和上下文跟 server.port=8080 server.servlet.context-path=/ # 配置Dubbo # 声明dubbo服务消费者的名称:保证唯一性 spring.application.name=013-springboot-dubbo-consumer # 设置注册中心的地址端口号 spring.dubbo.registry=zookeeper://localhost:2181控制层方法。@Reference注解表示在这其中引用远程接口服务。package com.szh.springboot.controller; import com.alibaba.dubbo.config.annotation.Reference; import com.szh.springboot.service.StudentService; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; /** * */ @Controller public class StudentController { @Reference(interfaceClass = StudentService.class,version = "1.0.0",check = false) private StudentService studentService; @RequestMapping(value = "/student/count") public @ResponseBody Object studentCount() { Integer allStudentCount=studentService.queryAllStudentCount(); return "学生总人数为:" + allStudentCount; } }pom文件和服务提供者是一样的,这里不再给出代码了。最后是SpringBoot项目启动入口类。package com.szh.springboot; import com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication //开启Spring注解配置 @EnableDubboConfiguration //开启Dubbo注解配置 public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }2.4 启动测试!!!因为我们这个案例是SpringBoot集成Dubbo,同时使用注册中心。所以启动的步骤是:1.    启动zookeeper注册中心 zkServer.cmd(我这里为了考虑电脑性能,所以直接就在Windows上启动了,推荐是在Linux上启动)2.    启动服务提供者(对应该工程的SpringBoot项目启动入口类)3.    启动服务消费者(对应该工程的SpringBoot项目启动入口类)
文章
Dubbo  ·  Java  ·  应用服务中间件  ·  Linux  ·  Windows  ·  Spring  ·  容器
2022-06-17
Dubbo——对版本号version的理解与使用
1.Dubbo中的版本号每个接口都应定义版本号,为后续不兼容升级提供可能。当一个接口有不同的实现,项目早期使用的一个实现类, 之后创建接口的新的实现类。区分不同的接口实现使用 version。特别是项目需要把早期接口的实现全部换位新的实现类,也需要使用 version。可以用版本号从早期的接口实现过渡到新的接口实现,版本号不同的服务相互间不引用。可以按照以下的步骤进行版本迁移:·       在低压力时间段,先升级一半提供者为新版本·       再将所有消费者升级为新版本·       然后将剩下的一半提供者升级为新版本2.案例分析最近两天一直都在学习Dubbo,说来说去,那开始依旧是三个工程(第一个是maven java工程、后两个是maven web工程)。 下面是这三个工程的架构。2.1 第一个是maven java工程这其中提供的是服务模型(实体Bean)、服务接口(对外提供的方法),这个工程不需要添加任何依赖。package com.szh.dubbo.model; import java.io.Serializable; /** * */ public class User implements Serializable { private Integer id; private String username; //getter and setter }package com.szh.dubbo.service; import com.szh.dubbo.model.User; /** * */ public interface UserService { User queryUserById(Integer id,String username); }2.2 第二个是maven web工程这个代表的是服务提供者,其中包含对第一个maven java工程中服务接口方法的实现。但是我们这里为服务接口提供两个实现类,来体现对版本号version的使用。package com.szh.dubbo.service.impl; import com.szh.dubbo.model.User; import com.szh.dubbo.service.UserService; /** * */ public class UserServiceImpl implements UserService { @Override public User queryUserById(Integer id, String username) { User user=new User(); user.setId(id); user.setUsername(username + "-1"); return user; } }package com.szh.dubbo.service.impl; import com.szh.dubbo.model.User; import com.szh.dubbo.service.UserService; /** * */ public class UserServiceImpl2 implements UserService { @Override public User queryUserById(Integer id, String username) { User user=new User(); user.setId(id); user.setUsername(username + "-2"); return user; } }然后是dubbo服务提供者的配置文件。这里仍然使用zookeeper注册中心,将服务接口的两个实现类加载到spring容器中,最后在web.xml中配置spring的监听器,同时读取dubbo配置文件。<?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://dubbo.apache.org/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <dubbo:application name="009-zk-userservice-multi-provider"/> <dubbo:protocol name="dubbo" port="20880"/> <dubbo:registry address="zookeeper://localhost:2181"/> <dubbo:service interface="com.szh.dubbo.service.UserService" ref="userServiceImpl" version="1.0.0"/> <dubbo:service interface="com.szh.dubbo.service.UserService" ref="userServiceImpl2" version="2.0.0"/> <bean id="userServiceImpl" class="com.szh.dubbo.service.impl.UserServiceImpl"/> <bean id="userServiceImpl2" class="com.szh.dubbo.service.impl.UserServiceImpl2"/> </beans><?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:dubbo-userservice-multi-provider.xml</param-value> </context-param> </web-app>pom文件中的相关依赖。 <!-- Spring依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.5.RELEASE</version> </dependency> <!-- SpringMVC依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.5.RELEASE</version> </dependency> <!-- Dubbo依赖 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> </dependency> <!-- 接口工程依赖 --> <dependency> <groupId>com.szh.dubbo</groupId> <artifactId>006-zk-interface</artifactId> <version>1.0.0</version> </dependency> <!-- Zookeeper依赖 --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>4.1.0</version> </dependency>2.3 第三个是maven web工程这个代表的是服务消费者,其中包含一个控制层方法的实现,去响应之前的服务接口。package com.szh.dubbo.controller; import com.szh.dubbo.model.User; import com.szh.dubbo.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; /** * */ @Controller public class UserController { @Autowired private UserService userService1; @Autowired private UserService userService2; @RequestMapping(value = "/userDetail") public String userDetail(Model model,Integer id,String username) { User user1=userService1.queryUserById(id,username); User user2=userService2.queryUserById(id,username); model.addAttribute("user1",user1); model.addAttribute("user2",user2); return "userDetail"; } }然后是dubbo服务消费者的配置文件、Spring配置文件。<?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://dubbo.apache.org/schema/dubbo" xmlns:dubo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <dubbo:application name="010-zk-multi-consumer"/> <dubo:registry address="zookeeper://localhost:2181"/> <dubbo:reference id="userService1" interface="com.szh.dubbo.service.UserService" version="1.0.0"/> <dubbo:reference id="userService2" interface="com.szh.dubbo.service.UserService" version="2.0.0"/> </beans><?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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <context:component-scan base-package="com.szh.dubbo.controller"/> <mvc:annotation-driven/> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"/> <property name="suffix" value=".jsp"/> </bean> </beans>最后是web.xml和控制层方法对应的jsp页面。<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml,classpath:dubbo-multi-consumer.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app><%@ page contentType="text/html;charset=utf-8" language="java" %> <html> <head> <title>$</title> </head> <body> <h3>用户1的信息</h3> <div>用户编号:${user1.id}</div> <div>用户姓名:${user1.username}</div> <hr/> <h3>用户2的信息</h3> <div>用户编号:${user2.id}</div> <div>用户姓名:${user2.username}</div> </body> </html>2.4 启动测试!!!
文章
Dubbo  ·  Java  ·  应用服务中间件  ·  Maven  ·  Spring  ·  容器
2022-06-17
Dubbo——认识Zookeeper注册中心、Windows&Linux下安装Zookeeper
1.Zookeeper注册中心对于服务提供方,它需要发布服务,而且由于应用系统的复杂性,服务的数量、类型也不断膨胀;对于服务消费方,它最关心如何获取到它所需要的服务,而面对复杂的应用系统,需要管理大量的服务调用。而且,对于服务提供方和服务消费方来说,他们还有可能兼具这两种角色,即需要提供服务,有需要消费服务。 通过将服务统一管理起来,可以有效地优化内部应用对服务发布/使用的流程和管理。服务注册中心可以通过特定协议来完成服务对外的统一。Dubbo 提供的注册中心有如下几种类型可供选:·       Multicast 注册中心:组播方式·       Redis 注册中心:使用 Redis 作为注册中心·       Simple 注册中心:就是一个 dubbo 服务。作为注册中心。提供查找服务的功能。·       Zookeeper 注册中心:使用 Zookeeper 作为注册中心推荐使用 Zookeeper 注册中心。1.1 注册中心的工作方式Zookeeper是一个高性能的,分布式的,开放源码的分布式应用程序协调服务。简称 zk。Zookeeper是翻译管理是动物管理员。可以理解为 windows 中的资源管理器或者注 册表。他是一个树形结构。这种树形结构和标准文件系统相似。ZooKeeper 树中的每个节点被称为Znode。和文件系统的目录树一样,ZooKeeper 树中的每个节点可以拥有子节点。每个节点表示一个唯一服务资源。Zookeeper 运行需要 java 环境。2.Zookeeper的下载与安装2.1 Windows官网:https://zookeeper.apache.org/下载之后解压到一个指定好的目录就可以了。然后进到 zookeeper 根目录下,创建一个data文件夹,之后进入到 zookeeper 根目录下的 conf 目录中,找到zoo_sample.cfg配置文件,复制一份,改名为 zoo.cfg,用记事本打开,添加以下内容:改完之后,进入bin目录下,找到 zkServer.cmd,启动Zookeeper。看到红色框中的内容,说明你的Zookeeper已经启动成功了。2.2 Linux下载步骤这里就不再多说了。直接说将zookeeper上传到Linux,然后安装启动的步骤。这里我进入到了 /usr/local 目录下,创建了一个 tools 目录,将zookeeper的压缩包上传到这个目录中,然后解压。解压完成之后,改个名,看起来顺眼。。。下面的步骤就跟上面说Windows中安装差不多了。在zookeeper根目录下创建一个 data 目录,然后进入zookeeper的conf目录下,复制zoo_sample.cfg名为zoo.cfg,vim命令进入修改,添加以下内容。保存退出之后,回到zookeeper根目录下的bin目录中,./zkServer.sh start 启动zookeeper即可。这里使用 ps -ef | grep zookeeper 查看已启动的zookeeper服务。当然也可以使用 ./zkServer.sh stop 关闭 zookeeper。
文章
Dubbo  ·  NoSQL  ·  Java  ·  应用服务中间件  ·  Linux  ·  Redis  ·  开发工具  ·  Windows
2022-06-17
Dubbo——Dubbo中的常用标签、服务化最佳实践
文章目录:1.Dubbo中的常用标签2.Dubbo中的服务化最佳实践2.1 分包2.2 粒度2.3 版本 2.4 案例分析2.4.1 003-link-interface2.4.2 004-link-userservice-provider2.4.3 005-link-consumer2.4.4 启动测试1.Dubbo中的常用标签Dubbo中常用标签。分为三个类别:公用标签,服务提供者标签,服务消费者标签。·       公用标签:配置应用信息<dubbo:application/> 和  配置注册中心 <dubbo:registry/>·       服务提供者标签:配置暴露的服务 <dubbo:service interface=”服务接口名” ref=”服务实现对象 bean”>·       服务消费者标签:引用远程服务<dubbo:reference id=”服务引用 bean 的 id” interface=”服务接口名”/>2.Dubbo中的服务化最佳实践2.1 分包建议将服务接口、服务模型、服务异常等均放在公共包中。2.2 粒度服务接口尽可能大粒度,每个服务方法应代表一个功能,而不是某功能的一个步骤,否则将面临分布式事务问题,Dubbo 暂未提供分布式事务支持。服务接口建议以业务场景为单位划分,并对相近业务做抽象,防止接口数量爆炸。不建议使用过于抽象的通用接口,如:Map query(Map),这样的接口没有明确语义,会给后期维护带来不便。2.3 版本每个接口都应定义版本号,为后续不兼容升级提供可能,如:<dubbo:service interface="com.xxx.XxxService" version="1.0" />。建议使用两位版本号,要变更服务版本。先升级一半提供者为新版本,再将消费者全部升为新版本,然后将剩下的一半提供者升为新版本。 2.4 案例分析在这个案例分析中,一共需要3个maven工程 。2.4.1 003-link-interface第一个是maven java工程,它里面存放的是服务模型和服务接口。代码如下:👇👇👇package com.szh.dubbo.model; import java.io.Serializable; /** * */ public class User implements Serializable { private Integer id; private String username; //getter and setter }package com.szh.dubbo.service; import com.szh.dubbo.model.User; /** * */ public interface UserService { User queryUserById(Integer id); Integer queryAllUserCount(); }2.4.2 004-link-userservice-provider​第二个是maven web工程,它里面存放的是服务提供者的相关信息。其中包括对服务接口的实现、服务提供者的dubbo配置文件信息、web.xml配置文件信息。代码如下:👇👇👇package com.szh.dubbo.service.impl; import com.szh.dubbo.model.User; import com.szh.dubbo.service.UserService; /** * */ public class UserServiceImpl implements UserService { @Override public User queryUserById(Integer id) { User user=new User(); user.setId(id); user.setUsername("张起灵"); return user; } @Override public Integer queryAllUserCount() { return 21; } }<?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://dubbo.apache.org/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!-- 声明dubbo服务提供者的名称:保证唯一性 --> <dubbo:application name="004-link-userservice-provider"/> <!-- 设置dubbo使用的协议和端口号 --> <dubbo:protocol name="dubbo" port="20880"/> <!-- 暴露服务接口 --> <dubbo:service interface="com.szh.dubbo.service.UserService" ref="userService" registry="N/A"/> <!-- 将业务接口的实现类加载到Spring容器中 --> <bean id="userService" class="com.szh.dubbo.service.impl.UserServiceImpl"/> </beans><?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- 读取dubbo配置文件信息 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:dubbo-userservice-provider.xml</param-value> </context-param> <!-- 配置Spring的监听器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>第三个是maven web工程,它里面存放的是服务消费者的相关信息。其中包括对控制层的实现、服务消费者的dubbo配置文件信息、Spring配置文件信息、web.xml配置文件信息以及控制层响应的jsp页面。代码如下:👇👇👇package com.szh.dubbo.controller; import com.szh.dubbo.model.User; import com.szh.dubbo.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; /** * */ @Controller public class UserController { @Autowired private UserService userService; @RequestMapping(value = "/userDetail") public String userDetail(Integer id, Model model) { User user=userService.queryUserById(id); Integer allUserCount=userService.queryAllUserCount(); model.addAttribute("user",user); model.addAttribute("allUserCount",allUserCount); return "userDetail"; } }<?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://dubbo.apache.org/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!-- 声明服务消费者名称:保证唯一性 --> <dubbo:application name="005-link-consumer"/> <!-- 引用远程接口服务 --> <dubbo:reference interface="com.szh.dubbo.service.UserService" id="userService" url="dubbo://localhost:20880" registry="N/A"/> </beans><?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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 组件扫描器,扫描controller包下的注解 --> <context:component-scan base-package="com.szh.dubbo.controller"/> <!-- 开启SpringMVC注解驱动 --> <mvc:annotation-driven/> <!-- 配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"/> <property name="suffix" value=".jsp"/> </bean> </beans><?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- 配置SpringMVC的中央调度器,读取Spring、Dubbo配置文件信息 --> <servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml,classpath:dubbo-consumer.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app><%@ page contentType="text/html;charset=utf-8" language="java" %> <html> <head> <title>$</title> </head> <body> <h3>用户详情</h3> <div>用户编号:${user.id}</div> <div>用户姓名:${user.username}</div> <div>用户总人数:${allUserCount}</div> </body> </html>2.4.4 启动测试为后两个maven web工程配置各自的Tomcat服务器,之后启动测试。配置步骤可以参考这篇博客的结尾部分:https://blog.csdn.net/weixin_43823808/article/details/117335107下面是测试结果,可以看到jsp页面中成功获取到了后端传来的数据。这就是Dubbo的服务化最佳实践。
文章
Dubbo  ·  Java  ·  应用服务中间件  ·  Maven  ·  Spring
2022-06-17
Dubbo——初识RPC、Dubbo框架、使用直连方式实现Dubbo
文章目录:1.RPC & 软件架构1.1 单一应用架构1.2 分布式微服务架构1.3 RPC2.Dubbo概述2.1基本架构2.2 dubbo支持的协议3.直连方式实现dubbo3.1 服务提供者的创建3.2 服务消费者的创建3.3 启动测试!!!1.RPC & 软件架构1.1 单一应用架构当网站流量很小时,应用规模小时,只需一个应用,将所有功能都部署在一起,以减少部署服务器数量和成本。此时,用于简化增删改查工作量的数据访问框架(ORM) 是关键。数据库的处理时间影响应用的性能。这种结构的应用适合小型系统,小型网站,或者企业的内部系统,用户较少,请求量不大,对请求的处理时间没有太高的要求。将所有功能都部署到一个服务器,简单易用。开发项目的难度低。缺点:         1、性能扩展比较困难        2、不利于多人同时开发        3、不利于升级维护        4、整个系统的空间占用比较大1.2 分布式微服务架构分布式系统是若干独立计算机(服务器)的集合,这些计算机对于用户来说就像单个相关系统,分布式系统(distributed system )是建立在网络之上的服务器端一种结构。分布式系统中的计算机可以使用不同的操作系统,可以运行不同应用程序提供服务,将服务分散部署到多个计算机服务器上。当应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的分布式服务框架(RPC) 是关键。分布式系统将服务作为独立的应用,实现服务共享和重用。1.3 RPCRPC【Remote Procedure Call】是指远程过程调用,是一种进程间通信方式,是一种技术思想,而不是规范。它允许程序调用另一个地址空间(网络的另一台机器上)的过程或函数,而不用开发人员显式编码这个调用的细节。调用本地方法和调用远程方法一样。RPC调用过程:通讯是基于TCP或 UDP协议;序列化方式(xml/json/二进制)1.    调用方 client 要使用右侧server 的功能(方法),发起对方法的调用2.    client stub 是RPC 中定义的存根,看做是 client 的助手。stub 把要调用的方法参数进行序列化,方法名称和其他数据包装起来。3.    通过网络 socket(网络通信的技术),把方法调用的细节内容发送给右侧的 server 4.    server 端通过socket 接收请求的方法名称、参数等数据,传给 stub。5.    server 端接到的数据由serverstub(server 的助手)处理,调用 server 的真正方法,处理业务 6.    server 方法处理完业务,把处理的结果对象(Object)交给了助手,助手把 Object 进行序列化,对象转为二进制数据。7.    server 助手二进制数据交给网络处理程序8.    通过网络将二进制数据,发送给 client。 9.    client 接数据,交给client 助手。10.client 助手,接收数据通过反序列化为java 对象(Object),作为远程方法调用结果。 2.Dubbo概述Apache Dubbo (incubating) |ˈdʌbəʊ| 是一款高性能、轻量级的开源 Java RPC 框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的RPC 远程服务调用方案、服务治理方案。官网:Apache Dubbo2.1基本架构1.    服务提供者( (Provider) ):暴露服务的服务提供方,服务提供者在启动时,向注册中心注册自己提供的服务。2.    服务消费者( (Consumer): 调用远程服务的服务消费方,服务消费者在启动时,向注册中心订阅自己所需的服务,服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。3.    注册中心( (Registry) ):注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。4.    监控中心( (Monitor) ):服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。·       服务容器负责启动,加载,运行服务提供者。·       服务提供者在启动时,向注册中心注册自己提供的服务。·       服务消费者在启动时,向注册中心订阅自己所需的服务。·       注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。·       服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。·       服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。2.2 dubbo支持的协议支持多种协议:dubbo , hessian , rmi , http, webservice , thrift , memcached , redis。dubbo 官方推荐使用 dubbo 协议。dubbo协议默认端口 20880使用 dubbo 协议,spring 配置文件加入:<dubbo:protocol name="dubbo" port="20880" />3.直连方式实现dubbo点对点的直连项目:消费者直接访问服务提供者,没有注册中心。消费者必须指定服务提供者的访问地址(url)。消费者直接通过 url 地址访问固定的服务提供者。这个 url 地址是不变的。3.1 服务提供者的创建1.创建一个maven web工程:服务的提供者,添加需要的依赖2.创建一个实体bean查询的结果(必须实现序列化)3.提供一个服务接口:xxxx4.实现这个服务接口:xxxxImpl5.配置dubbo服务提供者的核心配置文件   a.声明dubbo服务提供者的名称:保证唯一   b.声明dubbo使用的协议和端口号   c.暴露服务,使用直连方式6.添加监听器,读取配置文件信息代码如下:👇👇👇(代码顺序对应上面的序号) <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.5.RELEASE</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> </dependency>package com.szh.dubbo.model; import java.io.Serializable; /** * */ public class User implements Serializable { private Integer id; private String name; private Integer age; //getter and setter }package com.szh.dubbo.service; import com.szh.dubbo.model.User; /** * */ public interface UserService { User queryUserById(Integer id); }package com.szh.dubbo.service.impl; import com.szh.dubbo.model.User; import com.szh.dubbo.service.UserService; /** * */ public class UserServiceImpl implements UserService { @Override public User queryUserById(Integer id) { User user=new User(); user.setId(id); user.setName("张起灵"); user.setAge(21); return user; } }<?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://dubbo.apache.org/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!-- 声明dubbo服务提供者的名称:保证唯一性 --> <dubbo:application name="001-link-userservice-provider"/> <!-- 设置dubbo使用的协议和端口号 --> <dubbo:protocol name="dubbo" port="20880"/> <!-- 暴露服务接口 --> <dubbo:service interface="com.szh.dubbo.service.UserService" ref="a" registry="N/A"/> <!-- 将业务接口的实现类加载到Spring容器中 --> <bean id="a" class="com.szh.dubbo.service.impl.UserServiceImpl"/> </beans><?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- 读取dubbo配置文件信息 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:dubbo-userservice-provider.xml</param-value> </context-param> <!-- 配置Spring的监听器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>3.2 服务消费者的创建1.创建一个maven web工程:服务的消费者2.配置pom文件:添加需要的依赖(spring,dubbo)3.编写controller4.设置dubbo的核心配置文件()5.配置中央调度器(就是一个servlet:DispatcherServlet)代码如下:(代码顺序对应上面的序号)服务提供者接口中的方法要给消费者使用,消费者项目需要知道接口名称和接口中的方法名称、参数等。这些信息服务提供者才知道。需要把服务提供者接口对应工程的 class 文件打包为 jar 。服务接口项目的类文件打包为 jar, 安装到maven 仓库,仓库中的提供者 jar 可以被消费者使用。使用 idea 的 maven 生命周期中的install 命令进行打包(打包的时候将pom文件中的 <packaging>war</packaging> 内容注释掉,因为在服务消费者的pom文件中进行依赖项的导入是一个jar包)。也就是下面pom文件中的最后一个依赖项。1.      <dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.5.RELEASE</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> </dependency> <dependency> <groupId>com.szh.dubbo</groupId> <artifactId>001-link-userservice-provider</artifactId> <version>1.0.0</version> </dependency>package com.szh.dubbo.controller; import com.szh.dubbo.model.User; import com.szh.dubbo.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; /** * */ @Controller public class UserController { @Autowired private UserService userService; @RequestMapping(value = "/user") public String userDetail(Integer id, Model model) { User user=userService.queryUserById(id); model.addAttribute("user",user); return "userDetail"; } }<?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://dubbo.apache.org/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!-- 声明服务消费者名称:保证唯一性 --> <dubbo:application name="002-link-consumer"/> <!-- 引用远程接口服务 --> <dubbo:reference interface="com.szh.dubbo.service.UserService" id="userService" url="dubbo://localhost:20880" registry="N/A"/> </beans><?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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 组件扫描器,扫描controller包下的注解 --> <context:component-scan base-package="com.szh.dubbo.controller"/> <!-- 开启SpringMVC注解驱动 --> <mvc:annotation-driven/> <!-- 配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"/> <property name="suffix" value=".jsp"/> </bean> </beans><?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- 配置SpringMVC的中央调度器,读取Spring、Dubbo配置文件信息 --> <servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml,classpath:dubbo-consumer.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app><%@ page contentType="text/html;charset=utf-8" language="java" %> <html> <head> <title>$</title> </head> <body> <h1>用户详情</h1> <div>用户编号:${user.id}</div> <div>用户姓名:${user.name}</div> </body> </html>3.3 启动测试!!!上面两步,我们已经创建好了服务提供者和服务消费者,下面分别为这两个maven web工程配置各自的tomcat服务器。配置信息如下:👇👇👇(均不设置上下文根)配置好Tomcat之后,我们就可以启动测试了,这里需要注意的是:一定要先启动第一个maven web工程(服务提供者)的tomcat服务器;启动成功后,再启动第二个maven web工程的(服务消费者)tomcat服务器。因为顾名思义:肯定是先有提供,才能进行消费啊。下面是测试结果:👇👇👇(访问控制层中的请求路径,可以正确的拿到数据,这就说明我们使用直连方式实现了dubbo)
文章
负载均衡  ·  监控  ·  Dubbo  ·  算法  ·  Java  ·  应用服务中间件  ·  Apache  ·  Maven  ·  微服务  ·  Spring
2022-06-17
1
...
7 8 9 10 11 12
...
20
跳转至:
微服务
22893 人关注 | 10279 讨论 | 22911 内容
+ 订阅
  • 全链路灰度新功能:MSE上线配置标签推送
  • 如何在 ACK 中使用 MSE Ingress
  • ECS使用体验
查看更多 >
开发与运维
5310 人关注 | 127358 讨论 | 212173 内容
+ 订阅
  • 全链路灰度新功能:MSE上线配置标签推送
  • 如何在 ACK 中使用 MSE Ingress
  • 【Django | 开发】 (国际化项目&支持多语言)
查看更多 >
云原生
230971 人关注 | 10248 讨论 | 31594 内容
+ 订阅
  • 如何在 ACK 中使用 MSE Ingress
  • Spring实战入门教程,5天轻松掌握Spring框架
  • 瑞数信息再次入选Gartner《2022年中国ICT技术成熟度曲线报告》云安全示例厂商
查看更多 >
数据库
249924 人关注 | 45702 讨论 | 67148 内容
+ 订阅
  • 全链路灰度新功能:MSE上线配置标签推送
  • ECS使用体验
  • 【Django | allauth】登录_注册_邮箱验证_密码邮箱重置
查看更多 >
人工智能
2647 人关注 | 10120 讨论 | 71298 内容
+ 订阅
  • 教你如何玩转Modelscope (一)
  • 如何在 ACK 中使用 MSE Ingress
  • 【Django | 开发】 (国际化项目&支持多语言)
查看更多 >