栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

三、微服务场景模拟

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

三、微服务场景模拟

目录
  • 创建父工程
  • 创建服务提供者
  • 创建服务调用者
  • 存在的问题

学了黑马的SpringCloud后,整个项目工程结构:

创建父工程

先创建一个父工程,然后后续的工程都以这个工程为父。在实际开发中,每个微服务可独立一个工程。

工程目录结构:

在pom文件中添加对应依赖:



    4.0.0

    com.itheima
    heima-springcloud
    pom
    1.0-SNAPSHOT
    
        org.springframework.boot
        spring-boot-starter-parent
        2.1.5.RELEASE
        
    

    
        1.8
        Greenwich.SR1
        2.1.5
        8.0.22
    

    
        
            
            
                org.springframework.cloud
                spring-cloud-dependencies
                ${spring-cloud.version}
                pom
                import
            
            
            
                tk.mybatis
                mapper-spring-boot-starter
                ${mapper.starter.version}
            
            
            
                mysql
                mysql-connector-java
                ${mysql.version}
            
            
                org.springframework.cloud
                spring-cloud-starter-config
            
        
    
    
        
            org.projectlombok
            lombok
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    

这里已经对大部分要用到的依赖的版本进行了 管理,方便后续使用

创建服务提供者

新建一个项目user-service,对外提供查询用户的服务。

对应pom文件:



    
        heima-springcloud
        com.itheima
        1.0-SNAPSHOT
    
    4.0.0

    user-service

    
        8
        8
    

    
        
            org.springframework.boot
            spring-boot-starter-web
        
        
        
            tk.mybatis
            mapper-spring-boot-starter
            ${mapper.starter.version}
        
        
        
            mysql
            mysql-connector-java
            ${mysql.version}
        
        
    


编写配置文件:
创建 user-servicesrcmainresourcesapplication.yml 属性文件,这里我们采用了yaml语法,而不是properties

server:
	port: 9091
spring:
	datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springcloud?serverTimezone=UTC
    username: root
    password: 123456@root
mybatis:
	type-aliases-package: com.itheima.user.pojo

使用mysql图形界面工具创建 springcloud 数据库,创建tb_user表

USE springcloud;
SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for tb_user
-- ----------------------------
DROP TABLE IF EXISTS `tb_user`;
CREATE TABLE `tb_user` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
  `user_name` VARCHAR(100) DEFAULT NULL COMMENT '用户名',
  `password` VARCHAR(100) DEFAULT NULL COMMENT '密码',
  `name` VARCHAR(100) DEFAULT NULL COMMENT '姓名',
  `age` INT(10) DEFAULT NULL COMMENT '年龄',
  `sex` TINYINT(1) DEFAULT NULL COMMENT '性别,1男性,2女性',
  `birthday` DATE DEFAULT NULL COMMENT '出生日期',
  `note` VARCHAR(255) DEFAULT NULL COMMENT '备注',
  `created` DATETIME DEFAULT NULL COMMENT '创建时间',
  `updated` DATETIME DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `username` (`user_name`)
) ENGINE=INNODB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of tb_user
-- ----------------------------
INSERT INTO `tb_user` VALUES ('1', 'zhangsan', '123456', '张三', '30', '1', '1964-08-08', '张三同学在学Java', '2014-09-19 16:56:04', '2014-09-21 11:24:59');
INSERT INTO `tb_user` VALUES ('2', 'lisi', '123456', '李四', '21', '2', '1995-01-01', '李四同学在传智学Java', '2014-09-19 16:56:04', '2014-09-19 16:56:04');
INSERT INTO `tb_user` VALUES ('3', 'wangwu', '123456', '王五', '22', '2', '1994-01-01', '王五同学在学php', '2014-09-19 16:56:04', '2014-09-19 16:56:04');
INSERT INTO `tb_user` VALUES ('4', 'zhangliu', '123456', '张六', '20', '1', '1996-09-01', '张六同学在传智播客学Java', '2014-09-19 16:56:04', '2014-09-19 16:56:04');
INSERT INTO `tb_user` VALUES ('5', 'lina', '123456', '李娜', '28', '1', '1988-01-01', '李娜同学在传智播客学Java', '2014-09-19 16:56:04', '2014-09-19 16:56:04');
INSERT INTO `tb_user` VALUES ('6', 'lilei', '123456', '李雷', '23', '1', '1993-08-08', '李雷同学在传智播客学Java', '2014-09-20 11:41:15', '2014-09-20 11:41:15');
INSERT INTO `tb_user` VALUES ('7', 'hanmeimei', '123456', '韩梅梅', '24', '2', '1992-08-08', '韩梅梅同学在传智播客学php', '2014-09-20 11:41:15', '2014-09-20 11:41:15');
INSERT INTO `tb_user` VALUES ('8', 'itcast', '123456', '传智播客', '21', '2', '2008-07-08', '传智播客搞IT教育', '2014-09-20 11:41:15', '2014-09-20 11:41:15');
INSERT INTO `tb_user` VALUES ('9', 'heima', '123456', '黑马', '18', '2', '2012-08-08', '黑马是传智播客高端品牌', '2014-09-20 11:41:15', '2014-09-20 11:41:15');
INSERT INTO `tb_user` VALUES ('10', 'linus', '123456', '林纳斯', '45', '2', '1971-08-08', '林纳斯搞了linux又搞git', '2014-09-20 11:41:15', '2014-09-20 11:41:15');
INSERT INTO `tb_user` VALUES ('11', 'leijun', '123456', '雷布斯', '33', '2', '1983-08-08', '小爱同学;are you ok', '2014-09-20 11:41:15', '2014-09-20 11:41:15');
INSERT INTO `tb_user` VALUES ('12', 'madaye', '123456', '马大爷', '46', '2', '1980-08-08', '马大爷花呗可以不还吗', '2014-09-20 11:41:15', '2014-09-20 11:41:15');

编写 user-servicesrcmainjavacomitheimauserUserApplication.java 启动类:

package com.itheima.user;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import tk.mybatis.spring.annotation.MapperScan;

@SpringBootApplication
@MapperScan(basePackages = "com.itheima.user.mapper")//扫描通用mapper所在包
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

编写 user-servicesrcmainjavacomitheimauserpojoUser.java 实体类:

package com.itheima.user.pojo;

import lombok.Data;
import tk.mybatis.mapper.annotation.KeySql;

import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;


@Data
@Table(name = "tb_user")
public class User{
    // id
    @Id
    //开启主键自动回填
    @KeySql(useGeneratedKeys = true)
    private Long id;

    // 用户名
    private String userName;

    // 密码
    private String password;

    // 姓名
    private String name;

    // 年龄
    private Integer age;

    // 性别,1男性,2女性
    private Integer sex;

    // 出生日期
    private Date birthday;

    // 创建时间
    private Date created;

    // 更新时间
    private Date updated;

    // 备注
    private String note;
}

编写 user-servicesrcmainjavacomitheimausermapperUserMapper.java

package com.itheima.user.mapper;

import com.itheima.user.pojo.User;
import tk.mybatis.mapper.common.Mapper;

public interface UserMapper extends Mapper {

}

编写 user-servicesrcmainjavacomitheimauserserviceUserService.java

package com.itheima.user.service;

import com.itheima.user.mapper.UserMapper;
import com.itheima.user.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


@Service
public class UserService {

    @Autowired
    UserMapper userMapper;

    
    public User queryById(Long id){
        return userMapper.selectByPrimaryKey(id);
    }
}

添加一个对外查询的接口处理器
user-servicesrcmainjavacomitheimausercontrollerUserController.java

package com.itheima.user.controller;

import com.itheima.user.pojo.User;
import com.itheima.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Controller;
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.RestController;


@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    UserService userService;
    
    @GetMapping("/{id}")
    public User queryById(@PathVariable Long id){
        return userService.queryById(id);
    }
}

创建完成后项目结构图:

启动 user-service 项目,访问接口:http://localhost:9091/user/8

创建服务调用者

与上面类似,这里不再赘述,需要注意的是,我们调用 user-service 的功能,因此不需要mybatis相关依赖了。

consumer-demo对应pom文件:



    
        heima-springcloud
        com.itheima
        1.0-SNAPSHOT
    
    4.0.0

    consumer

    
        8
        8
    
    
        
            org.springframework.boot
            spring-boot-starter-web
        
    


编写启动类 consumer-demosrcmainjavacomitheimaconsumerConsumerApplication.java 并在其中注入 RestTemplate 具体如下:

package com.itheima.consumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

创建实体类
consumer-demosrcmainjavacomitheimaconsumerpojoUser.java

package com.itheima.consumer.pojo;

import lombok.Data;

import java.util.Date;


@Data
public class User{
    // id
    private Long id;

    // 用户名
    private String userName;

    // 密码
    private String password;

    // 姓名
    private String name;

    // 年龄
    private Integer age;

    // 性别,1男性,2女性
    private Integer sex;

    // 出生日期
    private Date birthday;

    // 创建时间
    private Date created;

    // 更新时间
    private Date updated;

    // 备注
    private String note;
}

编写 consumer-demosrcmainjavacomitheimaconsumercontrollerConsumerController.java ,在controller中直接调用RestTemplate,远程访问 user-service 的服务接口:

package com.itheima.consumer.controller;
import com.itheima.consumer.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
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.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping("/consumer")
public class ConsumerController {
	@Autowired
	private RestTemplate restTemplate;
	@GetMapping("{id}")
	public User queryById(@PathVariable Long id){
		String url = "http://localhost:9091/user/" + id;
		return restTemplate.getForObject(url, User.class);
	}
}

启动测试
启动 consumer-demo 引导启动类;因为 consumer-demo 项目没有配置端口,那么默认就是8080,我们访问:http://localhost:8080/consumer/8

存在的问题

user-service:对外提供了查询用户的接口
consumer-demo:通过RestTemplate访问 http://locahost:9091/user/{id} 接口,查询用户数据
存在什么问题?

  • 在consumer中,我们把url地址硬编码到了代码中,不方便后期维护
  • consumer需要记忆user-service的地址,如果出现变更,可能得不到通知,地址将失效
  • consumer不清楚user-service的状态,服务宕机也不知道
  • user-service只有1台服务,不具备高可用性
  • 即便user-service形成集群,consumer还需自己实现负载均衡
    其实上面说的问题,概括一下就是分布式服务必然要面临的问题:
  • 服务管理
    如何自动注册和发现
    如何实现状态监管
    如何实现动态路由
  • 服务如何实现负载均衡
  • 服务如何解决容灾问题
  • 服务如何实现统一配置

以上的问题,都将在SpringCloud中得到解决。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/288257.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号