赞
踩
目录
引入相关依赖(dubbo、zookeeper、Dubbo_api)
编写service层代码(这里的@Service就是Spring的注解)
编写PageController(该控制层的作用就是跳转到对应页面)
部分图片来自百战尚学堂
分布式就是很多“人”一起干不一样的事,合起来就是一件大事,意思就是一个大的业务系统,拆分成一个个小的业务模块,分别部署到不同的机器上
优点:解耦,代码复用性更高,独立部署,独立测试
单机架构就是一个“人”干所有事,集群架构就是多个“人”干相同的事,分布式架构就是不同的“人”干不同的事,但是合起来就是在干一件大事
单机架构的缺点就是当这个“人”出了一些故障,那么整个系统都将崩溃,代码耦合度较高,复用性不高,测试起来复杂。优点就是体系小,开发快,集群架构也是类似的
分布式架构的优点就是代码耦合度低,没有单点故障问题,一个“人”出错了,并不会影响其他“人”,代码复用性高,测试方便。缺点就是会导致体系变得庞大
Dubbo是一个RPC框架,作用就是让远程调用像本地调用一样简单、方便,通常使用Zookeeper+Dubbo实现分布式系统
什么是RPC:RPC让你用别人家的东西就像自己家的一样。
RPC两个作用:
常用的RPC框架
RPC是一种技术思想而非一种规范或协议。
常见 RPC 技术和框架:
注册中心Registry
在Dubbo微服务体系中,注册中心是其核心组件之一。Dubbo通过注册中心实现了分布式环境中各服务之间的注册与发现,是各个分布式节点之间的纽带。
其主要作用如下:
服务提供者Provider
服务的提供方
服务消费者Consumer
调用远程服务的服务消费方
监控中心Monitor
主要负责监控统计调用次数和调用时间等。
@Service、@Reference
@Service:将类注册到注册中心
@Reference:将类从注册中心拉取到本地
高级特性其实就是@Service、@Reference注解的一些属性
网络传输数据都是以二进制的形式进行传输的,但调用方请求的出入参数都是对象,此时就需要这些对象实现了Serializable方法,即可序列化,这样才能在网络中传输
打个比方:就像送快递一样,你的货物就相当于那个对象,货物需要打包相当于对象需要序列化为二进制,当对象到你手上的时候就是一串二进制,就像快递包到了你手上一样,此时就需要拆开快递包即可拿到自己的货物,就相当于反序列化一样将二进制变回对象
注册中心挂了,服务是否可以正常访问?
答案:
因为dubbo服务消费者在第一次调用时,会将服务提供方地址缓存到本地,以后在调用则不会访问注册中心。服务提供者地址发生变化时,注册中心会通服务消费者。
问题:
服务生产者端配置超时时间
使用timeout属性配置超时时间,默认值1000,单位毫秒。
@Service(timeout = 3000) //当前服务3秒超时
消费端配置超时时间
@Reference(timeout=2000)// 远程注入
private IOrderService iOrderService;
超时问题:
如果出现网络抖动,则会出现请求失败。
如何解决
Dubbo提供重试机制来避免类似问题的发生。
重试机制配置
@Service(timeout = 3000,retries = 2)
Dubbo提供多版本的配置,方便我们做服务的灰度发布,或者是解决不兼容的问题。
灰度发布(金丝雀发布):
当出现新功能时,会让一部分用户先使用新功能,用户反馈没问题时,再将所有用户迁移到新功能。
版本迁移步骤
多版本配置
老版本服务提供者配置
@Service(version = "1.0.0") 设置版本为1.0
新版本服务提供者配置
@Service(version = "2.0.0") 设置版本为2.0
新版本服务消费者配置
@Reference(version="2.0.0") 代表拉取的是2.0版本的该对象
private IOrderService iOrderService;// 订单服务
如果不需要区分版本,可以按照以下的方式配置 :
@Reference(version="*")
private IOrderService iOrderService;// 订单服务
Dubbo是一个分布式服务框架,能避免单点故障和支持服务的横向扩容。一个服务通常会部署多个实例。
问题:
订单服务生产者会出现单点故障。
如何从多个服务 Provider 组成的集群中挑选出一个进行调用,就涉及到一个负载均衡的策略。
Dubbo内置负载均衡策略
负载均衡策略配置
如果不指定负载均衡,默认使用随机负载均衡。我们也可以根据自己的需要,显式指定一个负载均衡。
生产者服务
@Service(timeout=3000,retries=3,loadbalance="roundrobin")
消费者服务
@Reference(timeout=2000,loadbalance="roundrobin")
参数:
Dubbo框架为服务集群容错提供了一系列好的解决方案,在此称为dubbo服务集群容错模式。
容错模式
集群容错配置
在消费者服务配置
@Reference(cluster = "failover")
private IOrderService iOrderService;
服务降级,当服务器压力剧增的情况下,根据当前业务情况及流量对一些服务和页面有策略的降级,以此释放服务器资源以保证核心任务的正常运行。
两种场景:
为什么需要降级
当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有损服务。
服务降级方式
第一种
mock=force:return null
含义:
表示消费方对该服务的方法调用都直接返回null值,不发起远程调用。用来屏蔽不重要服务不可用时对调用方的影响。
第二种
mock=fail:return null
含义:
表示消费方对该服务的方法调用在失败后,再返回null值,不抛异常。用来容忍不重要服务不稳定时对调用方的影响。
服务降级演示
@Reference(timeout = 2000,mock = "force:return null")
private IOrderService iOrderService;
并发控制
@Service(executes = 10)
注意:
服务端并发执行(或占用线程池线程数)不能超过10个
连接控制
@Service(actives= 10)
注意:
占用连接的请求的数不能超过10个。
//通过注解中的cache属性配置结果缓存机制
@Reference(cache="lru")
需求:完成用户的增删改查操作
技术栈:
前端:html、thymeleaf
分布式:Dubbo、Zookeeper、SpringMVC
持久化:MySql、MyBatisPlus
项目架构:
1、在Dubbo_father的pom文件中定义需要用的依赖的版本并配置jdk版本,在配置中有一个标签叫做dependencyManagement,这个标签的作用就是声明该依赖的版本,当子模块引入该依赖时,无需定义版本,可以直接使用父项目定义好的版本
- <?xml version="1.0" encoding="UTF-8"?>
- <project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <groupId>com.itbaizhan</groupId>
- <artifactId>Dubbo_father</artifactId>
- <packaging>pom</packaging>
- <version>1.0-SNAPSHOT</version>
- <modules>
- <module>Dubbo_producer</module>
- <module>Dubbo_api</module>
- <module>dubbo_consumer</module>
- </modules>
-
- <properties>
- <dubbo.spring.starter.version>2.7.6</dubbo.spring.starter.version>
- <dubbo.registry.zookeeper.version>2.7.6</dubbo.registry.zookeeper.version>
- <mybatisplus.spring.starter.version>3.5.0</mybatisplus.spring.starter.version>
- <mysql.connector.version>5.1.49</mysql.connector.version>
- </properties>
-
- <!-- 通过management提前声明这些依赖所使用的版本,等子项目使用的时候即可不需要定义版本,直接使用父项目声明的版本 -->
- <dependencyManagement>
- <dependencies>
- <!-- Dubbo 依赖 -->
- <dependency>
- <groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-spring-boot-starter</artifactId>
- <version>${dubbo.spring.starter.version}</version>
- </dependency>
- <!-- zookeeper 注册中心 依赖 -->
- <dependency>
- <groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-registry-zookeeper</artifactId>
- <version>${dubbo.registry.zookeeper.version}</version>
- </dependency>
- <!-- Mybatis plus 依赖 -->
- <dependency>
- <groupId>com.baomidou</groupId>
- <artifactId>mybatis-plus-boot-starter</artifactId>
- <version>${mybatisplus.spring.starter.version}</version>
- </dependency>
- <!--MySQL 数据库依赖 -->
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>${mysql.connector.version}</version>
- </dependency>
- </dependencies>
- </dependencyManagement>
-
- <!-- 设置jdk版本 -->
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>3.1</version>
- <configuration>
- <source>11</source>
- <target>11</target>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-
-
- </project>
因为Dubbo_consumer模块是SpringBoot项目,所以他的父项目是SpringBoot的起步依赖spring-boot-stater-parent,所以我们需要添加第二个父项目,通过dependencyManagement标签即可实现
- <?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>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>2.7.11</version>
- <relativePath/> <!-- lookup parent from repository -->
- </parent>
- <!-- 引入第二个父亲 -->
- <dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>com.itbaizhan</groupId>
- <artifactId>Dubbo_father</artifactId>
- <type>pom</type>
- <version>1.0-SNAPSHOT</version>
- <scope>import</scope>
- </dependency>
- </dependencies>
- </dependencyManagement>
- <groupId>com.itbaizhan</groupId>
- <artifactId>dubbo_consumer</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <name>dubbo_consumer</name>
- <description>Demo project for Spring Boot</description>
- <properties>
- <java.version>11</java.version>
- </properties>
- <dependencies>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-thymeleaf</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- <configuration>
- <excludes>
- <exclude>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </exclude>
- </excludes>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
- </project>
创建数据库和表
- 创建数据库
- create database test;
- 创建用户表
- CREATE TABLE user
- (
- id BIGINT(20) NOT NULL COMMENT '主键ID',
- name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
- age INT(11) NULL DEFAULT NULL COMMENT '年龄',
- PRIMARY KEY(id)
- );
创建User实体类(User实体类需要实现Serializable接口,前面有提到过)
- package com.itbaizhan.pojo;
-
- import lombok.AllArgsConstructor;
- import lombok.Data;
- import lombok.NoArgsConstructor;
-
- import java.io.Serializable;
-
- /**
- * 用户实体类
- */
- @Data
- @AllArgsConstructor
- @NoArgsConstructor
- public class User implements Serializable {
- public Long id;//用户id
- public String name;//用户名字
- public int age;//用户年龄
- }
mapper模块引入pojo模块
引入MybatisPlus和mysql依赖
- <?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">
- <parent>
- <artifactId>Dubbo_producer</artifactId>
- <groupId>com.itbaizhan</groupId>
- <version>1.0-SNAPSHOT</version>
- </parent>
- <modelVersion>4.0.0</modelVersion>
-
- <artifactId>mapper</artifactId>
-
- <dependencies>
- <!-- 引入pojo -->
- <dependency>
- <groupId>com.itbaizhan</groupId>
- <artifactId>pojo</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- <!-- MyBatisPlus依赖 -->
- <dependency>
- <groupId>com.baomidou</groupId>
- <artifactId>mybatis-plus-boot-starter</artifactId>
- </dependency>
- <!-- MySql依赖 -->
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- </dependency>
- </dependencies>
- </project>
编写UserMapper
- package com.itbaizhan.mapper;
-
- import com.baomidou.mybatisplus.core.mapper.BaseMapper;
- import com.itbaizhan.pojo.User;
-
- public interface UserMapper extends BaseMapper<User> {
- }
将producer修改为SpringBoot项目,因为SpringBoot项目的父类是spring-boot-stater-parent,而本身项目的父类是dubbo_producer,所以需要通过dependencyManagement引入第二个父项目
- <?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">
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>2.7.11</version>
- <relativePath/> <!-- lookup parent from repository -->
- </parent>
-
- <dependencyManagement>
- <dependencies>
- <!-- 引入第二个父项目 -->
- <dependency>
- <artifactId>Dubbo_producer</artifactId>
- <groupId>com.itbaizhan</groupId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- </dependencies>
- </dependencyManagement>
- <modelVersion>4.0.0</modelVersion>
-
- <artifactId>producer</artifactId>
-
-
- </project>
引入mapper模块,通过依赖传递的方式引入pojo模块
- <dependencies>
- <dependency>
- <groupId>com.itbaizhan</groupId>
- <artifactId>mapper</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- </dependencies>
编写启动类并扫描持久层接口创建相应的实现类放到spring容器中
- package com.itbaizhan.producer;
-
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
-
- @SpringBootApplication
- @MapperScan("com.itbaizhan.mapper")
- public class ProducerApplication {
- public static void main(String[] args) {
- SpringApplication.run(ProducerApplication.class,args);
- }
- }
配置数据源
- spring:
- datasource:
- driver-class-name: com.mysql.jdbc.Driver
- url: jdbc:mysql://192.168.138.101/test
- username: root
- password: 123456
添加pojo模块依赖
- <?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">
- <parent>
- <artifactId>Dubbo_father</artifactId>
- <groupId>com.itbaizhan</groupId>
- <version>1.0-SNAPSHOT</version>
- </parent>
- <modelVersion>4.0.0</modelVersion>
-
- <artifactId>Dubbo_api</artifactId>
- <dependencies>
- <dependency>
- <groupId>com.itbaizhan</groupId>
- <artifactId>pojo</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- </dependencies>
-
-
- </project>
编写api模块service层接口(该接口的作用是定义producer模块的service规范)
- package com.itbaizhan.service;
-
- import com.itbaizhan.pojo.User;
-
- import java.util.List;
-
- public interface UserService {
- //新增用户
- public void add(User user);
-
- //根据id删除用户
- public void delete(Long userId);
-
- //根据id修改用户
- public void update(User user);
-
- //查询所有用户
- public List<User> selectAll();
- //根据id查询用户
- public User selectById();
-
- }
producer模块引入相关依赖
- <?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">
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>2.7.11</version>
- <relativePath/> <!-- lookup parent from repository -->
- </parent>
-
- <dependencyManagement>
- <dependencies>
- <!-- 引入第二个父项目 -->
- <dependency>
- <groupId>com.itbaizhan</groupId>
- <artifactId>Dubbo_father</artifactId>
- <type>pom</type>
- <version>1.0-SNAPSHOT</version>
- <scope>import</scope>
- </dependency>
- </dependencies>
- </dependencyManagement>
-
- <modelVersion>4.0.0</modelVersion>
-
- <artifactId>producer</artifactId>
-
- <dependencies>
- <dependency>
- <groupId>com.itbaizhan</groupId>
- <artifactId>mapper</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- <!-- 引入dubbo -->
- <dependency>
- <groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-spring-boot-starter</artifactId>
- </dependency>
- <!-- 引入zookeeper -->
- <dependency>
- <groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-registry-zookeeper</artifactId>
- </dependency>
- <!-- 引入dubbo_api模块 -->
- <dependency>
- <groupId>com.itbaizhan</groupId>
- <artifactId>Dubbo_api</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- </dependencies>
- </project>
编写producer模块service层代码(类的上方需要添加Dubbo的@Service注解,将该类注册到注册中心)
- package com.itbaizhan.producer.service;
-
- import com.itbaizhan.mapper.UserMapper;
- import com.itbaizhan.pojo.User;
- import org.apache.dubbo.config.annotation.Service;
- import org.springframework.beans.factory.annotation.Autowired;
-
- import java.util.List;
-
- @Service
- public class UserService implements com.itbaizhan.service.UserService {
-
- @Autowired
- private UserMapper userMapper;
-
- /**
- * 添加用户
- * @param user
- */
- @Override
- public void add(User user) {
- userMapper.insert(user);
- }
-
- /**
- * 根据id删除用户
- * @param userId
- */
- @Override
- public void delete(Long userId) {
- userMapper.deleteById(userId);
- }
-
- /**
- * 根据id修改用户
- * @param user
- */
- @Override
- public void update(User user) {
- userMapper.updateById(user);
- }
-
- /**
- * 查询所有用户
- * @return
- */
- @Override
- public List<User> selectAll() {
- return userMapper.selectList(null);
- }
-
- /**
- * 根据id查询用户
- * @param userId
- * @return
- */
- @Override
- public User selectById(Long userId) {
- return userMapper.selectById(userId);
- }
- }
配置dubbo和zookeeper
- dubbo:
- #项目名字
- application:
- name: myProducer
- #注册中心地址
- registry:
- address: zookeeper://192.168.138.101:2181
- timeout: 50000
- #端口号和协议名
- protocol:
- port: 20880
- name: dubbo
- #扫描的包
- scan:
- base-packages: com.itbaizhan.producer.service
运行producer模块启动类,通过dubbo-admin查看是否注册到了注册中心
- <!-- 引入dubbo -->
- <dependency>
- <groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-spring-boot-starter</artifactId>
- </dependency>
- <!-- 引入zookeeper -->
- <dependency>
- <groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-registry-zookeeper</artifactId>
- </dependency>
- <!-- 引入dubbo_api模块 -->
- <dependency>
- <groupId>com.itbaizhan</groupId>
- <artifactId>Dubbo_api</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
通过@Reference拉取Dubbo_api模块的UserService,那么此时会有小伙伴问了:我们注册的是producer模块的UserService,为什么拉取的确实Dubbo_api模块的UserService呢?
这是因为采用了jdk动态代理的模式,就是拉取这个接口的实现类,以接口引用的方式实现调用
- package com.itbaizhan.dubbo_consumer.service;
-
- import com.itbaizhan.pojo.User;
- import org.apache.dubbo.config.annotation.Reference;
- import org.springframework.stereotype.Service;
-
- import java.util.List;
-
- @Service
- public class UserService {
- @Reference
- private com.itbaizhan.service.UserService userService;
-
- //新增用户
- public void add(User user){
- userService.add(user);
- }
-
- //根据id删除用户
- public void delete(Long userId){
- userService.delete(userId);
- }
-
- //根据id修改用户
- public void update(User user){
- userService.update(user);
- }
-
- //查询所有用户
- public List<User> selectAll(){
- return userService.selectAll();
- }
-
- //根据id查询用户
- public User selectById(Long userId){
- return userService.selectById(userId);
- }
- }
- package com.itbaizhan.dubbo_consumer.controller;
-
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.PathVariable;
- import org.springframework.web.bind.annotation.RequestMapping;
-
- @Controller
- public class PageController {
-
- @RequestMapping("/{page}")
- public String page(@PathVariable String page){
- return page;
- }
- }
- package com.itbaizhan.dubbo_consumer.controller;
-
- import com.itbaizhan.dubbo_consumer.service.UserService;
- import com.itbaizhan.pojo.User;
- import org.springframework.beans.factory.annotation.Autowired;
- 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 java.util.List;
-
- @Controller
- @RequestMapping("/user")
- public class UserController {
- @Autowired
- private UserService userService;
-
- //新增用户
- @PostMapping("/add")
- public String add(User user){
- userService.add(user);
- return "redirect:/ok";
- }
-
- //根据id删除用户
- @GetMapping("/delete")
- public String delete(Long userId){
- userService.delete(userId);
- return "redirect:/ok";
- }
-
- //根据id修改用户
- @GetMapping("/preUpdate")
- public String preUpdate(Long userId, Model model){
- User user = userService.selectById(userId);
- model.addAttribute("user",user);
- return "update";
- }
-
- //根据id查询用户
- @PostMapping("/update")
- public String update(User user){
- userService.update(user);
- return "redirect:/ok";
- }
-
- //查询所有用户
- @GetMapping("/selectAll")
- public String selectAll(Model model){
- List<User> userList = userService.selectAll();
- model.addAttribute("userList",userList);
- return "showuser";
- }
-
- }
-
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>主页</title>
- </head>
- <body>
- <a href="/adduser">添加用户</a>
- <a href="/user/selectAll">查询用户</a>
- </body>
- </html>
- dubbo:
- #项目名字
- application:
- name: myConsumer
- #注册中心地址
- registry:
- address: zookeeper://192.168.138.101:2181
- timeout: 50000
- #端口号和协议名
- protocol:
- port: 20881
- name: dubbo
- #扫描的包
- scan:
- base-packages: com.itbaizhan.dubbo_consumer.service
运行producer模块和consumer模块,访问localhost:8080/index
此时发现整个项目可以正常运行,那么我们就可以继续编写页面了
编写adduser.html
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>添加用户</title>
- </head>
- <body>
- <form action="/user/add" method="post">
- 用户名:<input type="text" name="name">
- 年龄:<input type="text" name="age"><br/>
- <input type="submit" value="提交">
- </form>
-
- </body>
- </html>
编写ok.html
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>操作成功</title>
- </head>
- <body>
- 操作成功,点击<a href="/index.html">返回首页</a>
- </body>
- </html>
点击添加用户
点击提交
查看是否添加用户成功
测试成功之后编写查询所有用户(需要用到thymeleaf)
编写showuser.html对用户有两个操作,修改和删除
- <!DOCTYPE html>
- <html lang="en" xmlns:th="http://www.thymeleaf.org">
- <head>
- <meta charset="UTF-8">
- <title>用户列表</title>
- </head>
- <body>
- <table border="1px solid black" align="center">
- <tr>
- <th>id</th>
- <th>用户姓名</th>
- <th>用户年龄</th>
- <th>操作</th>
- </tr>
- <tr th:each="user:${userList}">
- <td th:text="${user.id}"></td>
- <td th:text="${user.name}"></td>
- <td th:text="${user.age}"></td>
- <td>
- <a th:href="@{/user/preUpdate(userId=${user.id})}">修改</a>
- <a th:href="@{/user/delete(userId=${user.id})}">删除</a>
- </td>
- </tr>
- </table>
- </body>
- </html>
点击查询用户
编写update.html
- <!DOCTYPE html>
- <html lang="en" xmlns:th="http://www.thymeleaf.org">
- <head>
- <meta charset="UTF-8">
- <title>修改用户</title>
- </head>
- <body>
- <form action="/user/update" method="post">
- <!-- userId的隐藏域 -->
- <input type="hidden" name="id" th:value="${user.id}">
- 用户名:<input type="text" name="name" th:value="${user.name}">
- 年龄:<input type="text" name="age" th:value="${user.age}"><br/>
- <input type="submit" value="修改">
- </form>
- </body>
- </html>
点击修改用户
修改用户数据,点击修改按钮过后跳转到操作成功页面,回到首页再次查询用户会发现,用户数据已经更改
删除用户的业务在实现查询用户业务的时候已经写好了,只要点击删除即可删除用户
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。