微服务学习1——微服务环境搭建

news2024/11/28 8:45:09

微服务学习1——微服务环境搭建

(参考黑马程序员项目)
个人仓库地址:https://gitee.com/jkangle/springboot-exercise.git

微服务就是将单体应用进一步拆分,拆成更小的服务,拆完之后怎么调用,主流的技术有RESTful和RPC,(首先以RESTful为例子)

1.模块设计

shop-common 公共模块——相当于工具类

shop-user 用户微服务——存储用户的信息

shop-product 商品微服务——存储商品的所有信息

shop-order 订单微服务——存储订单的所有信息

【注意】所有的对数据库的操作是结合JPA

2.实现目标

通过订单微服务来查询商品的信息,也就是通过订单的微服务调用商品的微服务

在这里插入图片描述

3.具体实现

在这里插入图片描述

3.1创建一个父工程test

父工程做的内容就是规定好这个项目所有的版本号这些,因此只需要pom.xml文件即可

<?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>org.example</groupId>
    <artifactId>test</artifactId>
    <version>1.0-SNAPSHOT</version>


    <packaging>pom</packaging>
    <modules>
        <module>shop-common</module>
        <module>shop-users</module>
        <module>shop-product</module>
        <module>shop-order</module>
    </modules>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

        <spring-boot.version>2.7.3</spring-boot.version>
        <spring-cloud.version>2021.0.7</spring-cloud.version>
        <spring-cloud-alibaba.version>2.1.0.RELEASE</spring-cloud-alibaba.version>
        <fastjson.version>1.2.57</fastjson.version>
    </properties>

    <dependencyManagement>
        <dependencies>

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>${fastjson.version}</version>
            </dependency>

        </dependencies>
    </dependencyManagement>

</project>
3.2在父工程中创建公共模块

公共模块就是相当于是一个工具类,里面有数据库信息的实体类

package pojo;

import lombok.Data;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

/**
 * 订单的实体类
 */
@Entity(name = "shop_order")
@Data
public class Order {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)

    /**
     * 订单id
     */
    private int oid;
    /**
     * 用户id
     */
    private Integer uid;
    /**
     * 物品id
     */
    private Integer pid;
    /**
     * 物品名称
     */
    private String pname;
    /**
     * 物品价格
     */
    private Double pprice;
    /**
     * 用户姓名
     */
    private String username;
    /**
     * 购买数量
     */
    private Integer number;
}

package pojo;

import lombok.Data;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

/**
 *
 *
 * @author jkk
 * @since 2020-03-20-20:25
 */
@Entity(name = "shop_product")
@Data
public class Product {

    /**
     * 主键
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer pid;

    /**
     * 商品名称
     */
    private String pname;

    /**
     * 商品价格
     */
    private double pprice;

    /**
     * 库存
     */
    private Integer stock;

}

3.3在父工程中创建用户模块

用户模块就是实现与用户的表相关的操作,对用户的业务就放到这个模块中,所以每一个模块中必须有一个启动类Application,当然需要配置它的yml文件

package org.example.users;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

/**
 * @author jkk
 */
@SpringBootApplication
@EnableDiscoveryClient
public class ShopUsersApplications {
    public static void main(String[] args) {
        SpringApplication.run(ShopUsersApplications.class, args);
    }
}

server:
  port: 8071
spring:
  application:
    name: service-product
  datasource:
    url: jdbc:mysql://localhost:3306/shop?characterEncoding=UTF-8
    username: root
    password:
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    properties:
      hibernate:
        hbm2ddl:
          auto: update
        dialect: org.hibernate.dialect.MySQL5InnoDBDialect

当前微服务并没有使用,所以没有写相关的具体业务


3.4在父工程中创建商品模块

同理将商品所需要的业务写在里面

controller

package org.example.product.controller;

import com.alibaba.fastjson.JSON;
import org.example.product.service.ProductService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.RestController;
import pojo.Product;

@RestController
public class ProductController {

    private static final Logger log = LoggerFactory.getLogger(ProductController.class);

    @Autowired
    private ProductService productService;

    @GetMapping("/product/{pid}")
    public Product product(@PathVariable("pid") Integer pid) {
        Product product = productService.findByPid(pid);
        log.info("查询到商品:" + JSON.toJSONString(product));
        return product;
    }
}

dao

package org.example.product.dao;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import pojo.Product;

@Repository
public interface ProductDao extends JpaRepository<Product,Integer> {


}

service

package org.example.product.service;

import pojo.Product;

public interface ProductService {
     Product findByPid(Integer pid);
}

package org.example.product.service.impl;

import org.example.product.dao.ProductDao;
import org.example.product.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import pojo.Product;

import java.util.Optional;

@Service
public class ProductServiceImpl implements ProductService {

    @Autowired
    private ProductDao productDao;

    @Override
    public Product findByPid(Integer pid) {
        Optional<Product> optional = productDao.findById(pid);
        if (optional.isPresent()) {
            return optional.get();
        }
        return null;
    }

}

启动类

package org.example.product;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@EnableJpaRepositories
@SpringBootApplication
@EntityScan(basePackages = "pojo")
public class ProductApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProductApplication.class,args);
    }
}

配置文件

server:
  port: 8081

spring:
  application:
    name: service-product
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/shop?characterEncoding=UTF-8
    username: root
    password:
  jpa:
    properties:
      hibernate:
        hbm2ddl:
          auto: update
        dialect: org.hibernate.dialect.MySQL5InnoDBDialect


3.5在父工程中创建订单模块

controller

package org.example.controller;

import com.alibaba.fastjson.JSON;
import org.example.service.OrderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.RestController;
import org.springframework.web.client.RestTemplate;
import pojo.Order;
import pojo.Product;

/**
 * 使用restTemplate对象调用shop-product的请求方法
 */
@RestController
public class OrderController {
    private static final Logger log = LoggerFactory.getLogger(OrderController.class);
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private OrderService orderService;

    @GetMapping("/order/prod/{pid}")
    public Order order(@PathVariable("pid") Integer pid){
        Product product = restTemplate.getForObject("http://localhost:8081/product/" + pid, Product.class);
        log.info(">>商品信息,查询结果:" + JSON.toJSONString(product));
        Order order = new Order();
        order.setOid(1);
        order.setUid(1);
        order.setPid(product.getPid());
        order.setPname(product.getPname());
        order.setPprice(product.getPprice());
        order.setNumber(1);
        orderService.save(order);
        return order;
    }

}

dao

package org.example.dao;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import pojo.Order;
@Repository
public interface OrderDao extends JpaRepository<Order,Integer> {
}

service

package org.example.service;

import pojo.Order;

/**
 * 订单的service层接口
 */
public interface OrderService {
    /**
     * 将订单存到数据库
     * @param order
     */
    public void save(Order order);
}

package org.example.service.impl;

import org.example.dao.OrderDao;
import org.example.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import pojo.Order;

/**
 * service接口的实现
 */
@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderDao orderDao;

    /**
     * 存储订单
     * @param order
     */
    @Override
    public void save(Order order) {
        orderDao.save(order);
    }
}

启动类

package org.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.Bean;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.web.client.RestTemplate;

/**
 * shop-order的启动类
 * @author jkk
 */
@SpringBootApplication
@EnableJpaRepositories
@EntityScan(basePackages = "pojo")
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class,args);
    }

    @Bean
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

yml配置文件

server:
  port: 8091

spring:
  application:
    name: service-product
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/shop?characterEncoding=UTF-8
    username: root
    password:

  jpa:
    properties:
      hibernate:
        hbm2ddl:
          auto: update
        dialect: org.hibernate.dialect.MySQL5InnoDBDialect

4.运行

可以注意到,当前调用另一个微服务的时候是通过把服务提供者的网络地址 (ip,端口)等硬编码到了代码中

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【分布式】zabbix 6.0部署讲解

目录 一、 序章二、zabbix概念2.1 zabbix是什么&#xff1f;2.2 zabbix 监控原理2.3 zabbix 6.0 新特性2.4 zabbix 6.0 功能组件 三、zabbix 6.0 部署部署服务端3.1 部署 Nginx PHP 环境并测试3.1.1 安装nginx3.1.2 安装php3.1.3 修改 Nginx 配置3.1.4 修改 php 配置3.1.5 创建…

Python +selenium 自动化之元素定位

selenium之八大元素定位&#xff1a; 1、通过ID的方式定位 id是页面的唯一标识 例如&#xff1a;找到百度的搜索输入框 driver.findElement(By.id("kw")) 2、通过tagName的方式定位 用标签名定位非常少 ---一般会重复 driver.findElements(By.tagName(&qu…

Vue2 Diff 算法简易版

背景 最近复习的过程中&#xff0c;准备对比一下Vue2和Vue3的diff算法区别&#xff0c;好知道两者直接的差异和优缺点。刚好看了网上的文章&#xff0c;但是对方写的代码不太正确&#xff0c;所以特意记录一下我的学习过程~ 双端比较法 Vue2采用的双端比较法&#xff0c;即新…

MBD开发 STM32 Timer

开两个定时器 一快一慢 两个中断都要使能 没有自动更新&#xff0c;切换下timerx就好了&#xff0c;但是触发UP要手动勾选

剑指offer27.二叉树的镜像

这道题很简单&#xff0c;写了十多分钟就写出来了&#xff0c;一看题目就知道这道题肯定要用递归。先交换左孩子和右孩子&#xff0c;再用递归交换左孩子的左孩子和右孩子&#xff0c;交换右孩子的左孩子和右孩子&#xff0c;其中做一下空判断就行。以下是我的代码&#xff1a;…

爬虫入门指南(8): 编写天气数据爬虫程序,实现可视化分析

文章目录 前言准备工作爬取天气数据可视化分析完整代码解释说明 运行效果完结 前言 天气变化是生活中一个重要的因素&#xff0c;了解天气状况可以帮助我们合理安排活动和做出决策。本文介绍了如何使用Python编写一个简单的天气数据爬虫程序&#xff0c;通过爬取指定网站上的天…

Pandas+Pyecharts | 双十一美妆销售数据分析可视化

文章目录 &#x1f3f3;️‍&#x1f308; 1. 导入模块&#x1f3f3;️‍&#x1f308; 2. Pandas数据处理2.1 读取数据2.2 数据信息2.3 筛选有销量的数据 &#x1f3f3;️‍&#x1f308; 3. Pyecharts数据可视化3.1 双十一前后几天美妆订单数量3.2 双十一前后几天美妆销量3.3…

【Linux】线程终结篇:线程池以及线程池的实现

linux线程完结 文章目录 前言一、线程池的实现二、了解性知识 1.其他常见的各种锁2.读者写者问题总结 前言 什么是线程池呢&#xff1f; 线程池一种线程使用模式。线程过多会带来调度开销&#xff0c;进而影响缓存局部性和整体性能。而线程池维护着多个线程&#xff0c;等待着…

智能、安全、高效,看移远如何助力割草机智能化升级

提到割草机&#xff0c;大家可能首先会想到其噪声大、费人力、安全性不足等问题。智能割草机作为一种便捷、高效的智能割草设备&#xff0c;能够自主完成草坪修剪工作&#xff0c;很好地解决传统割草机的痛点问题。 随着人们对家庭园艺以及生活质量要求的逐步提高&#xff0c;割…

向量数据库:新一代的数据处理工具

在我们的日常生活中&#xff0c;数据无处不在。从社交媒体的帖子到在线购物的交易记录&#xff0c;我们每天都在产生和处理大量的数据。为了有效地管理这些数据&#xff0c;我们需要使用数据库。数据库是存储和管理数据的工具&#xff0c;它们可以按照不同的方式组织和处理数据…

python实现简单贪吃蛇

import math import pygame import time import numpy as np # 此模块包含游戏所需的常量 from pygame.locals import *# 设置棋盘的长宽 BOARDWIDTH 90 BOARDHEIGHT 50 # 分数 score 0# 豆子 class Food(object):def __init__(self):self.item (4, 5)# 画出食物def _draw(…

qtav源码包编译(qt5.15+msvc2019)、使用vlc media player串流生成rtsp的url并且在qml客户端中通过qtav打开

QTAV源码包编译 下载源码 下载依赖库&#xff08;里面有ffmepg等内容&#xff09; https://sourceforge.net/projects/qtav/files/depends/QtAV-depends-windows-x86x64.7z/download下载源码包 https://github.com/wang-bin/QtAV更新子模块 cd QtAV && git submod…

vmware postgresql大杂烩

Vmware 窗口过界&#xff1a; https://blog.csdn.net/u014139753/article/details/111603882 vmware, ubuntu 安装&#xff1a; https://zhuanlan.zhihu.com/p/141033713 https://blog.csdn.net/weixin_41805734/article/details/120698714 centos安装&#xff1a; https://w…

【Go】短信内链接拉起小程序

一、 需求场景 (1) 业务方&#xff0c;要求给用户发送的短信内含有可以拉起我们的小程序指定位置的链接&#xff1b; 【XXX】尊敬的客户&#xff0c;您好&#xff0c;由于您XX&#xff0c;请微信XX小程序-微信授权登录-个人中心去XX&#xff0c;如已操作请忽略&#xff0c;[…

Jenkins2.346新建项目时没有Maven项目选项解决办法

解决办法&#xff1a;需要安装Maven Integration 系统管理-->管理插件-->可选插件-->过滤输入框中输入搜索关键字&#xff1a; Maven Integration&#xff0c;下载好后安装。

Mysql:创建和管理表(全面详解)

创建和管理表 前言一、基础知识1、一条数据存储的过程2、标识符命名规则3、MySQL中的数据类型 二、创建和管理数据库1、创建数据库2、使用数据库3、修改数据库4、删除数据库 三、创建表1、创建方式12、创建方式23、查看数据表结构 四、修改表1、追加一个列2、修改一个列3、重命…

MySQL存储引擎(InnoDB、MyISAM、Memory面试题)

1.1 MySQL体系结构 1). 连接层 最上层是一些客户端和链接服务&#xff0c;包含本地sock 通信和大多数基于客户端/服务端工具实现的类似于 TCP/IP的通信。主要完成一些类似于连接处理、授权认证、及相关的安全方案。在该层上引入了线程池的概念&#xff0c;为通过认证安全接入的…

暑期学JavaScript【第六天】

一、正则表达式 边界符 ^&#xff1a;表示以后面字符开头 $&#xff1a;表示以前方字符结尾量词 *:前面的字符至少出现0次 :前面的字符至少出现1次 ?:前面的字符出现0/1次 {n}:重复n次 {n,}:至少重复n次 {n,m}:重复n~m次字符类 [ ]:代表字符集合 /^[a-z]$/[ ^ ] 取反 [^a-…

leetcode 257. 二叉树的所有路径

2023.7.5 这题需要用到递归回溯&#xff0c;也是我第一次接触回溯这个概念。 大致思路是&#xff1a; 在reversal函数中&#xff0c;首先将当前节点的值加入到路径path中。然后判断当前节点是否为叶子节点&#xff0c;即没有左右子节点。如果是叶子节点&#xff0c;将路径转化…

nnUNet保姆级使用教程!从环境配置到训练与推理(新手必看)

文章目录 写在前面nnUNet是什么&#xff1f;一、配置虚拟环境二、安装nnUNet框架1.安装nnUNet这一步我遇到的两个问题&#xff1a; 2.安装隐藏层hiddenlayer&#xff08;可选&#xff09; 三、数据集准备nnUNet对于你要训练的数据是有严格要求的&#xff0c;这第一点就体现在我…