从零开始学习微服务 -微服务基本概述、微服务案例

2023-10-31

1. SpringCloud概述

1.1 互联网应用架构

1.1.1 单体应用架构
  • 在诞⽣之初,项目的⽤户量、数据量规模都⽐较⼩,项目所有的功能模块都放在一个工程中编码、
    编译、打包并且部署在一个Tomcat容器中的架构模式就是单体应用架构,这样的架构既简单实 ⽤、便
    于维护,成本⼜低,成为了那个时代的主流架构⽅式。

    image-20220210143307925

image-20220210143315616

  • 单体项目优点

    • 高效开发:项⽬前期开发节奏快,团队成员少的时候能够快速迭代
    • 架构简单:MVC架构,只需要借助IDE开发、调试即可
    • 易于测试:只需要通过单元测试或者浏览器完成
    • 易于部署:打包成单⼀可执⾏的jar或者打成war包放到容器内启动
  • 单体架构的应用比较容易部署、测试, 在项目的初期,单体应用可以很好地运行。

  • 然而,随着需求的不断增加, 越来越多的人加入开发团队,代码库也在飞速地膨胀。慢慢地,单体应用变得越来越臃肿,可维护性、灵活性逐渐降低,维护成本越来越高。

  • 单体项目的缺点

    • 可靠性差: 某个应用Bug,例如死循环、内存溢出等, 可能会导致整个应用的崩溃
    • 复杂性高: 以一个百万行级别的单体应用为例,整个项目包含的模块多、模块的边界模糊、 依赖关系不清晰、 代码质量参差不齐、 混乱地堆砌在一起。使得整个项目非常复杂。
    • 扩展能力受限: 单体应用只能作为一个整体进行扩展,无法根据业务模块的需要进行伸缩。例如,
      应用中有的模块是计算密集型的,它需要强劲的CPU; 有的模块则是IO密集型的,需要更大的内
      存。 由于这些模块部署在一起,不得不在硬件的选择上做出妥协。
  • 业务量上涨之后,单体应用架构进一步丰富变化,比如应用集群部署、使用Nginx进行负载均衡、增加
    缓存服务器、增加文件服务器、数据库集群并做读写分离等,通过以上措施增强应对高并发的能力、应
    对一定的复杂业务场景,但依然属于单体应用架构。

    image-20220210144001911

1.1.2 垂直应用架构
  • 为了避免上⾯提到的那些问题,开始做模块的垂直划分,做垂直划分的原则是基于现有的业务
    特性来做,核心目标标第⼀个是为了业务之间互不影响,第⼆个是在研发团队的壮⼤后为了提⾼效率,
    减少组件之间的依赖。

    image-20220210144050828

  • 垂直应用架构优点

    • 系统拆分实现了流量分担,解决了并发问题
    • 可以针对不同模块进⾏优化
    • ⽅便⽔平扩展,负载均衡,容错率提⾼
    • 系统间相互独⽴,互不影响,新的业务迭代时更加⾼效
  • 垂直应用架构缺点

    • 服务之间相互调⽤,如果某个服务的端⼝或者ip地址发⽣改变,调⽤的系统得⼿动改变
    • 搭建集群之后,实现负载均衡⽐较复杂,如:内⽹负载,在迁移机器时会影响调⽤⽅的路 由,导致线上故障
    • 服务之间调⽤⽅式不统⼀,基于 httpclient 、 webservice ,接⼝协议不统⼀
    • 服务监控不到位:除了依靠端⼝、进程的监控,调⽤的成功率、失败率、总耗时等等这些监 控指标
      是没有的
1.1.3 SOA应用架构
  • 在做了垂直划分以后,模块随之增多,维护的成本在也变⾼,⼀些通⽤的业务和模块重复的越来越
    多,为了解决上⾯提到的接⼝协议不统⼀、服务⽆法监控、服务的负载均衡,引⼊了阿⾥巴巴开源的
    Dubbo ,⼀款⾼性能、轻量级的开源Java RPC框架,可以和Spring框架无缝集成。

  • 它提供了三⼤核⼼能⼒:⾯向接⼝的远程⽅法调⽤,智能容错和负载均衡,以及服务⾃动注册和发现。

  • SOA (Service-Oriented Architecture),即面向服务的架构。根据实际业务,把系统拆分成合适
    的、独立部署的模块,模块之间相互独立(通过Webservice/Dubbo等技术进行通信)。

  • 优点:分布式、松耦合、扩展灵活、可重用。

  • 缺点:服务抽取粒度较大、服务调用方和提供方耦合度较高(接口耦合度)

    image-20220210151341147

1.1.4 微服务架构
  • 微服务架构可以说是SOA架构的一种拓展,这种架构模式下它拆分粒度更小、服务更独立。把应用
    拆分成为一个个微小的服务,不同的服务可以使用不同的开发语言和存储,服务之间往往通过Restful等

  • 轻量级通信。微服务架构关键在于微小、独立、轻量级通信。微服务是在 SOA 上做的升华粒度更加细致,微服务架构强调的⼀个重点是业务需要彻底的组件化和服务化

    image-20220210151504329

1.2 微服务架构思想

  • 微服务架构设计的核心思想就是“微”,拆分的粒度相对比较小,这样的话单一职责、开发的耦合度
    就会降低、微小的功能可以独立部署扩展、灵活性强,升级改造影响范围小

  • 微服务架构的优点

    • 微服务很小,便于特定业务功能的聚焦
    • 微服务很小,每个微服务都可以被一个小团队单独实施(开发、测试、部署上线、运维),团队合
      作一定程度解耦,便于实施敏捷开发
    • 微服务很小,便于重用和模块之间的组装
    • 微服务很独立,那么不同的微服务可以使用不同的语言开发,松耦合
    • 微服务架构下,我们更容易引入新技术
  • 微服务架构的缺点

    • 微服务架构下,分布式复杂难以管理,当服务数量增加,管理将越加复杂;
    • 微服务架构下,分布式链路跟踪难等;

1.3 微服务架构核心概念

1.3.1 服务注册与发现
  • 服务注册与服务发现

    • 例如:职位搜索 ->简历服务
    • 服务提供者:简历服务
    • 服务消费者:职位搜索
  • 服务注册: 服务提供者将所提供服务的信息(服务器IP和端口、服务访问协议等)注册/登记到注册
    中心

  • 服务发现: 服务消费者能够从注册中心获取到较为实时的服务列表,然后根究一定的策略选择一个
    服务访问

    image-20220210151958966

image-20220210152019183

1.3.2 负载均衡
  • 负载均衡即将请求压力分配到多个服务器(应用服务器、数据库服务器等),以此来提高服务的性能、
    可靠性

    image-20220210152056863

1.3.3 链路追踪
  • 微服务架构越发流行,一个项目往往拆分成很多个服务,那么一次请求就需要涉及到很多个服务。不同
    的微服务可能是由不同的团队开发、可能使用不同的编程语言实现、整个项目也有可能部署在了很多服
    务器上(甚至百台、千台)横跨多个不同的数据中心。

  • 所谓链路追踪,就是对一次请求涉及的很多个服务链路进行日志记录、性能监控

    image-20220210154128113

1.3.4 API网关
  • 微服务架构下,不同的微服务往往会有不同的访问地址,客户端可能需要调用多个服务的接口才能
    完成一个业务需求,如果让客户端直接与各个微服务通信可能出现:
    • 客户端需要调用不同的url地址,增加了维护调用难度
    • 在一定的场景下,也存在跨域请求的问题(前后端分离就会碰到跨域问题,原本我们在后端采
      用Cors就能解决,现在利用网关,那么就放在网关这层做好了)
    • 每个微服务都需要进行单独的身份认证
  • 那么,API网关就可以较好的统一处理上述问题,API请求调用统一接入API网关层,由网关转发请
    求。API网关更专注在安全、路由、流量等问题的处理上(微服务团队专注于处理业务逻辑即可),它的
    功能比如
    • 统一接入(路由)
    • 安全防护(统一鉴权,负责网关访问身份认证验证,与“访问认证中心”通信,实际认证业务逻辑
      交移“访问认证中心”处理)
    • 黑白名单(实现通过IP地址控制禁止访问网关功能,控制访问)
    • 协议适配(实现通信协议校验、适配转换的功能)
    • 流量管控(限流)
    • 长短链接支持
    • 容错能力(负载均衡)

1.4 SpringCloud介绍

1.4.1 基本概述
  • Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分
    布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,
    都可以用 Spring Boot的开发风格做到一键启动和部署。
  • Spring Cloud并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
1.4.2 解决的问题
  • Spring Cloud 规范及实现意图要解决的问题其实就是微服务架构实施过程中存在的一些问题,比如
    微服务架构中的服务注册发现问题、网络问题(比如熔断场景)、统一认证安全授权问题、负载均衡问
    题、链路追踪等问题
  • Distributed/versioned configuration (分布式/版本化配置)
  • Service registration and discovery (服务注册和发现)
  • Routing (智能路由)
  • Service-to-service calls (服务调用)
  • Load balancing (负载均衡)
  • Circuit Breakers (熔断器)
  • Global locks (全局锁)
  • Leadership election and cluster state ( 选举与集群状态管理)
  • Distributed messaging (分布式消息传递平台)

1.5 SpringCloud架构

1.5.1 核心组件
  • Spring Cloud 生态圈中的组件,按照发展可以分为第一代 Spring Cloud组件和第二代 Spring
    Cloud组件。

    image-20220210154736540

1.5.2 体系结构

image-20220210154857495

  • Spring Cloud中的各组件协同工作,才能够支持一个完整的微服务架构。比如
  • 注册中心负责服务的注册与发现,很好将各服务连接起来
  • API网关负责转发所有外来的请求
  • 断路器负责监控服务之间的调用情况,连续多次失败进行熔断保护。
  • 配置中心提供了统一的配置信息管理服务,可以实时的通知各个服务获取最新的配置信息
1.5.4 与Bubbo对比
  • Dubbo是阿里巴巴公司开源的一个高性能优秀的服务框架,基于RPC调用,对于目前使用率较高的
    Spring Cloud Netflix来说,它是基于HTTP的,所以效率上没有Dubbo高,但问题在于Dubbo体系的组
    件不全,不能够提供一站式解决方案,比如服务注册与发现需要借助于Zookeeper等实现,而Spring
    Cloud Netflix则是真正的提供了一站式服务化解决方案,且有Spring大家族背景

    image-20220210155128494

2. 微服务案例

2.1 案例说明

  • 本部分我们按照普通方式模拟一个微服务之间的调用,后续我们将一步步使用Spring Cloud的组件对案
    例进行改造。

    image-20220210155401155

  • 完整业务流程图

    image-20220210155424263

2.2 环境准备

2.2.1 数据库搭建
CREATE TABLE products
(
    id          INT PRIMARY KEY AUTO_INCREMENT,
    NAME        VARCHAR(50),  #商品名称
    price       DOUBLE,
    flag        VARCHAR(2),   #上架状态
    goods_desc  VARCHAR(100), #商品描述
    images      VARCHAR(400), #商品图片
    goods_stock INT,          #商品库存
    goods_type  VARCHAR(20)   #商品类型
);
2.2.2 工程架构

image-20220210160221227

2.3 创建父工程

2.3.1 创建项目
  • 创建一个 maven 项目, 项目名为 lg-parent
2.3.2 添加maven配置
  • 添加maven配置 <packaging>pom</packaging> 修改打包方式为 pom

      <!-- 将打包方式修改为 pom -->
        <packaging>pom</packaging>
        <!--spring boot 父启动器依赖-->
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.6.RELEASE</version>
        </parent>
        <dependencies>
            <!--web依赖-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!--日志依赖-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </dependency>
            <!--测试依赖-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <!--lombok工具-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.4</version>
                <scope>provided</scope>
            </dependency>
            <!-- Actuator可以帮助你监控和管理Spring Boot应用-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
            <!--热部署-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <optional>true</optional>
            </dependency>
        </dependencies>
    
  • 添加打包插件

    <build>
            <plugins>
                <!--编译插件-->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>8</source>
                        <target>8</target>
                        <encoding>utf-8</encoding>
                    </configuration>
                </plugin>
                <!--打包插件-->
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <executions>
                        <execution>
                            <goals>
                                <goal>repackage</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    
  • 删除 src 目录

2.4 创建公共微服务

2.4.1 创建项目
  • 在 lg-parent下 创建一个maven项目, 项目名 lg-service-common
2.4.2 添加maven配置
  • maven配置如下 :

    <?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>lg-parent</artifactId>
            <groupId>cn.knightzz</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>lg-service-common</artifactId>
    
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>3.3.2</version>
            </dependency> 
            <!--pojo持久化使用-->
            <dependency>
                <groupId>javax.persistence</groupId>
                <artifactId>javax.persistence-api</artifactId>
                <version>2.2</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </dependency>
        </dependencies>
    
    </project>
    
2.4.3 生成实体类
  • 需要下载 MybatisX 插件

  • 点击数据库表, 选中插件

    image-20220211084715806
  • 生成实体类

    image-20220211103304229

    image-20220211103333591

  • 实体类代码

    package cn.knightzz.entity;
    
    import com.baomidou.mybatisplus.annotation.IdType;
    import com.baomidou.mybatisplus.annotation.TableField;
    import com.baomidou.mybatisplus.annotation.TableId;
    import com.baomidou.mybatisplus.annotation.TableName;
    import java.io.Serializable;
    import lombok.Data;
    
    /**
     * 
     * @author knightzz98
     * @TableName products
     */
    @TableName(value ="products")
    @Data
    public class Products implements Serializable {
    
        @TableId(type = IdType.AUTO)
        private Integer id;
        private String name;
        private Double price;
        private String flag;
        private String goodsDesc;
        private String images;
        private Integer goodsStock;
        private String goodsType;
        @TableField(exist = false)
        private static final long serialVersionUID = 1L;
    }
    

2.5 创建产品微服务

2.5.1 创建项目
  • 创建名为 lg-service-product 的微服务项目
2.5.2 添加配置
  • 引入公共微服务的依赖
<?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>lg-parent</artifactId>
        <groupId>cn.knightzz</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>lg-service-product</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>cn.knightzz</groupId>
            <artifactId>lg-service-common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>
  • 添加数据库连接配置

    server:
      port: 9000
    spring:
      application:
        # 微服务名称
        name: lg-service-product
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/spring_db?serverTimezone=UTC&characterEncoding=UTF-8
        username: root
        password: 123456
    
2.5.2 代码生成

image-20220211103525434

image-20220211103549933

  • 这里注意, 因为默认会生成 实体类, 所以我们需要删除 entity 包, 使用 lg-service-common 的实体类
2.5.3 Service层代码
  • ProductsService接口

    package cn.knightzz.service;
    
    import cn.knightzz.entity.Products;
    import com.baomidou.mybatisplus.extension.service.IService;
    
    /**
     *
     * @author knightzz98
     */
    public interface ProductsService extends IService<Products> {
    
    
        /**
         * 根据id查询产品信息
         * @param id
         * @return
         */
        public Products findById(Integer id);
    }
    
    
  • ProductsServiceImpl

    package cn.knightzz.service.impl;
    
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import cn.knightzz.entity.Products;
    import cn.knightzz.service.ProductsService;
    import cn.knightzz.mapper.ProductsMapper;
    import org.springframework.stereotype.Service;
    
    /**
     *
     * @author knightzz98
     */
    @Service
    public class ProductsServiceImpl extends ServiceImpl<ProductsMapper, Products>
        implements ProductsService{
    
        @Override
        public Products findById(Integer id) {
            // 可以直接使用 baseMapper 查询数据
            Products products = baseMapper.selectById(id);
            return products;
        }
    }
    
2.5.4 Controller层代码
package cn.knightzz.controller;

import cn.knightzz.entity.Products;
import cn.knightzz.service.ProductsService;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @author 王天赐
 * @title: ProductController
 * @projectName springcloud-lg
 * @description:
 * @website http://knightzz.cn/
 * @github https://github.com/knightzz1998
 * @date 2022/2/11 10:56
 */
@RestController
@RequestMapping("/products")
public class ProductController {

    @Resource
    ProductsService productsService;

    @RequestMapping("/query/{id}")
    public Products query(@PathVariable Integer id){
        return productsService.findById(id);
    }
}

2.5.5 创建启动类
package cn.knightzz;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("cn.knightzz.mapper")
public class ProductApplication {

    public static void main(String[] args) {
        SpringApplication.run(ProductApplication.class, args);
    }
}

2.5.5 代码测试
  • 打开 apipost 或者 postman 进行测试, 注意, 需要自己向数据库里面添加一些数据

    image-20220211113141510

2.6 页面静态化微服务

2.6.1 创建项目
  • 创建一个名为 lg-service-page 的maven项目
2.6.2 添加配置
  • 添加 maven 配置

     <dependencies>
            <dependency>
                <groupId>cn.knightzz</groupId>
                <artifactId>lg-service-common</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
        </dependencies>
    
  • application.yml

    server:
      port: 9100
    spring:
      application:
        # 微服务名称
        name: lg-service-page
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/spring_db?serverTimezone=UTC&characterEncoding=UTF-8
        username: root
        password: 123456
    
2.6.3 PageController
  • PageController

    package cn.knightzz.page.controller;
    
    import cn.knightzz.entity.Products;
    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;
    
    import javax.annotation.Resource;
    
    
    /**
     * @author 王天赐
     * @title: PageController
     * @projectName springcloud-lg
     * @description:
     * @website http://knightzz.cn/
     * @github https://github.com/knightzz1998
     * @date 2022/2/11 11:55
     */
    @RestController
    @RequestMapping("/page")
    public class PageController {
    
        @Resource
        private RestTemplate restTemplate;
    
        @GetMapping("/getData/{id}")
        public Products findDataById(@PathVariable Integer id){
    
            Products product = restTemplate.getForObject("http://localhost:9000/products/query/" + id, Products.class);
            System.out.println("从 lg-service-product 模块得到的数据 " + product);
            return product;
        }
    }
    
    
2.6.4 页面启动类
  • 页面启动类

    package cn.knightzz;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.Bean;
    import org.springframework.web.client.RestTemplate;
    
    @SpringBootApplication
    public class PageApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(PageApplication.class, args);
        }
    
        @Bean
        public RestTemplate restTemplate(){
            return  new RestTemplate();
        }
    }
    
    

2.7 案例代码存在的问题

  • 我们在页面静态化微服务中使用RestTemplate调用商品微服务的商品状态接口时(Restful API 接
    口)。在微服务分布式集群环境下会存在什么问题呢?怎么解决?
  • 存在的问题:
  • 在服务消费者中,我们把url地址硬编码到代码中,不方便后期维护。
  • 服务提供者只有一个服务,即便服务提供者形成集群,服务消费者还需要自己实现负载均衡。
  • 在服务消费者中,不清楚服务提供者的状态。
  • 服务消费者调用服务提供者时候,如果出现故障能否及时发现不向用户抛出异常页面?
  • RestTemplate这种请求调用方式是否还有优化空间?能不能类似于Dubbo那样玩?
  • 这么多的微服务统一认证如何实现?
  • 配置文件每次都修改好多个很麻烦!?
  • 上述分析出的问题,其实就是微服务架构中必然面临的一些问题:
  • 服务管理:自动注册与发现、状态监管
  • 服务负载均衡
  • 熔断
  • 远程过程调用
  • 网关拦截、路由转发
  • 统一认证
  • 集中式配置管理,配置信息实时自动更新
  • 这些问题,Spring Cloud 体系都有解决方案

3. 初代SpringCloud核心组件

  • 说明:上面提到网关组件Zuul性能一般,未来将退出Spring Cloud 生态圈

  • 各组件整体结构如下:

    image-20220211164634078

从形式上来说,Feign一个顶三,Feign = RestTemplate + Ribbon + Hystrix

image-20220211164658550

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从零开始学习微服务 -微服务基本概述、微服务案例 的相关文章

  • 如何以编程方式找出我的 PermGen 空间使用情况?

    我正在尝试诊断java lang OutOfMemoryError PermGen Space在 Sun 的 Hotspot JVM 上运行时出现错误 并且想知道我的程序在不同时刻使用了多少 PermGen 空间 有没有办法以编程方式找出这
  • 如何用Java写入OS系统日志?

    Mac OS 有一个名为 Console 的应用程序 其中包含记录的消息 错误和故障 我相信 Windows 中的等效项是事件查看器 我想 Linux 上也有一个 但我不知道它是什么 也不知道它在哪里 是否可以像这样从 Java 输出获取消
  • 如何使用 Java 将 HTML 内容转换为 PDF 而不丢失格式?

    我有一些 HTML 内容 包括格式化标签 例如strong 图像等 在我的 Java 代码中 我想将此 HTML 内容转换为 PDF 文档 而不丢失 HTML 格式 有没有办法用 Java 来实现 使用 iText 或任何其他库 I use
  • 如何在java中压缩/解压tar.gz文件

    谁能告诉我在java中压缩和解压缩tar gzip文件的正确方法我一直在搜索 但我能找到的最多的是zip或gzip 单独 我写了一个包装器公共压缩 http commons apache org compress called jarchi
  • Java Sqlite Gradle

    我对 gradle 和 java 还很陌生 我有一个使用 sqlite 的项目 它通过 intellij idea 运行良好 但我无法从终端运行它 它会抛出异常 java lang ClassNotFoundException org sq
  • JBoss AS 5 中的共享库应该放在哪里?

    我是 Jboss 新手 但我有多个 Web 应用程序 每个应用程序都使用 spring hibernate 和其他开源库和 portlet 所以基本上现在每个 war 文件都包含这些 jar 文件 如何将这些 jar 移动到一个公共位置 以
  • 如何在数据库中对 (Java) 枚举进行建模(使用 SQL92)

    您好 我正在使用名为 性别 的列对实体进行建模 在应用程序代码中 性别应该是一个 Java 枚举类型 有 2 个值 男性和女性 知道作为数据类型的枚举不是通用 SQL 语言 92 的一部分 您将如何建模它 数据模型必须是可移植的 以便由多个
  • 通过 JNI 从 Applet 调用 DLL

    我有一个 概念验证 的作品 它跨越了一些不熟悉的领域 我的任务是将 EFTPOS 机器连接到在内联网浏览器中作为小程序运行的应用程序 我暂时忽略了 EFTPOS dll 并用我选择的语言 Delphi 创建了一个简单的 JNI 修饰的 DL
  • 此版本不符合 Google Play 64 位要求,添加库后仍然出现错误

    我正在 Play 商店上传一个视频编辑器应用程序 其中包含带有一些本机代码的库 所以我通过将其添加到 gradle 来使其兼容 64 位 ndk abiFilters armeabi v7a arm64 v8a x86 x86 64 添加了
  • 中间件 API 的最佳实践是什么? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我们正在开发一个中间件 SDK 采用 C 和 Java 语言 供游戏开发人员 动画软件开发人员 阿凡达开
  • XSLT:我们可以使用abs值吗?

    我想知道在 XSLT 中我们是否可以使用 math abs 我在某处看到过这个 但它不起作用 我有类似的东西
  • 在多模块项目中访问绑定适配器

    我有一个多模块项目 其中应用程序模块包含我的绑定适配器 而我的功能模块取决于我的应用程序模块 因为它是动态功能模块 应用程序 包含绑定适配器 gt 动态功能模块 存在布局的地方 我在所有模块中启用了数据绑定和 kapt 我无法成功构建应用程
  • 删除 ArrayList 对象问题

    我在处理作业时遇到从 ArrayList 中删除对象的问题 如果我使用 正常 for 循环 它的工作原理如下 public void returnBook String isbn for int i 0 i lt booksBorrowed
  • 如何在 Java 中创建要打印到 JFrame 的 JLabels 数组

    我正在尝试制作一系列标签 每个标签都有一个来自函数的不同值 我不知道要使用的标签的确切数量 我的意思是可以打印任意数量的值 请帮我做这件事 很简单 只需一个方法返回一个数组或一些 JLabels 集合 并将它们全部添加到您的 JCompon
  • 无法仅在控制台中启动 androidstudio

    你好 我的问题是下一个 我下载了Android Studio如果我去 路径 android studio bin 我执行studio sh 我收到以下错误 No JDK found Please validate either STUDIO
  • 使用 Cucumber Scenario Outline 处理 Excel 电子表格

    如果可能的话 我试图找到一种更优雅的方法来处理从与 Excel 电子表格行 第 n 个 相关的 Cucumber Scenario Outline 中调用第 n 个数字 目前 我正在使用迭代编号来定义要从中提取数据的 Excel 电子表格的
  • Java 8根据Map属性过滤Map对象列表以删除一些重复项

    Have a List
  • 如何将任务添加到 gradle 中的主要“构建”任务

    当我尝试使用以下代码将任务添加到主构建任务时 rootProject tasks getByName build dependsOn mytask 当我跑步时它抱怨gradle w build输出 Where Build file line
  • C/C++ 通过 Android NDK 在 JNI 中看不到 Java 方法

    我正在尝试从使用 NDK 构建的 C 类文件调用 Java 方法 它不断抛出常见的 未找到非静态方法 错误并导致整个 Android 应用程序崩溃 下面的代码片段 有些东西可能不需要 但我按原样保留它们 因为焦点 问题在于refreshJN
  • RecyclerView 不调用 onCreateViewHolder 或 onBindView

    没有收到任何错误 所有数据似乎都有效 由于某种原因 没有调用与视图相关的方法 我已确定以下事项 getItemCount 是唯一被调用的适配器方法 并且返回一个正整数值 我知道这将是你们将要查看的区域 构造函数正在被调用 成员变量有效 Pa

随机推荐

  • JS中用window.open()方式打开,使新页面全屏、居中的代码

    window open 的介绍 1 基本语法 window open pageURL name parameters 2 各项参数 其中yes no也可使用1 0 pixel value为具体的数值 单位象素 参数 取值范围 说明 alwa
  • 基于亚马逊云科技无服务器服务快速搭建电商平台——性能篇

    使用 Serverless 构建独立站的优势 在传统架构模式下 如果需要进行电商大促需要提前预置计算资源以支撑高并发访问 会造成计算资源浪费并且增加运维工作量 本文介绍一种新的部署方式 将 WordPress 和 WooCommerce 部
  • java实现“两数之和”

    java代码如下 import java util Arrays import java util HashMap import java util Map import java util Scanner 问题 两数之和 给定一个数组 和
  • 凸优化系列——约束优化问题

    1 KKT条件 局部最优解 全局最优解 严格最优解 注意几类非光滑函数的转化 约束优化最优解的特征 最优解的一阶必要条件 Karush Kuhn Tucker KKT条件
  • CentOS 7 源码制作openssh 9.4p1 rpm包 —— 筑梦之路

    参考之前的博客 centos 7 制作openssh8 7 8 8 8 9 9 0 9 1 9 2 9 3 p1 rpm包升级 筑梦之路 openssh rpm包 筑梦之路的博客 CSDN博客 需要说明的是9 4版本必须要openssl 1
  • Windows2003系统漏洞提权复现

    操作系统 Microsoft Windows Server 2003 Web服务器 IIS V6 0 第一步 将大马文件上传至服务器根目录 第二步 访问大马文件 进入大马的控制界面 第三步 查看漏洞补丁信息 第四步 上传漏洞工具 将提权工具
  • 在Vue2项目中使用Vant组件库

    Vant 2 Mobile UI Components built on Vuehttps vant contrib gitee io vant v2 zh CN home1 安装vant包 Vue2项目下必须这么写 不能直接写npm i
  • MySQL 排序

    排序数据 1 排序规则 使用ORDER BY 字句排序 在其后面加所需字段 ASC ascend 升序 DESC descend 降序 ORDER BY 字句在SELECT语句的结尾 注意 数据库中默认按照先后添加顺序存储数据 在查询时 也
  • python中的sort的用法

    一 sort的两种用法 1 a sort 对原列表进行原址排序 原址排序的意思是原列表被改变了 排序的规则 数字 字符串按照ASCII 中文按照unicode从小到大排序 a 2 3 6 7 1 a sort print a 1 2 3 6
  • chrony系统授时时,几条重要命令输出信息的含义

    原文 https docs fedoraproject org en US Fedora 18 html System Administrators Guide sect Checking if chrony is synchronized
  • 确定你的public继承塑模出is-a关系——条款32

    如果你令class D Derived 以public形式继承class B Base 你便是告诉C 编译器 以及你的代码读者 说 每一个类型为D的对象同时也是一个类型为B的对象 反之不成立 你的意识是B比D表现出更一般化的概念 而D比B表
  • 开关电源-电容

    电子元器件 电容 1 电容是电路中重要的元件 种类多 用途广 主要有插件类和贴片类两种 2 电容主要特性参数 标称容量 耐压 误差 温度 2 1电容容量常用单位有微法 uF 纳法 nF 皮法 pF 单位换算 luF 103nF 106pF
  • 【数模】编码的传输问题 Huffman算法编程实现(matlab)

    编码的传输问题 利用Huffman算法编程实现以下问题 已知字母A B C D E F出现的概率 字母 概率 A 35 B 10 C 20 D 10 E 20 F 5 哈夫曼编码基础知识复习 哈夫曼编码 Huffman Coding 又称霍
  • Tensorflow框架(张量、计算图、会话)

    张量 计算图 会话 人工智能实践 Tensorflow笔记 Tensorflow框架 张量 计算图 会话 基于Tensorflow的NN 神经网络 用张量表示数据 用计算图搭建神经网络 用会话执行计算图 优化线上的权重 参数 得到模型 张量
  • 抓包工具fiddler不抓取火狐浏览器的数据

    fiddler可以抓到google浏览器的包 但是抓不到Firefox浏览器的包 火狐浏览器版本79 0 64 位 fiddler 4 亲测好使 操作步骤 打开Fiddler gt 菜单栏 Tools gt Options gt Conne
  • sdf转smi

    from rdkit import Chem smi Chem MolToSmiles Chem SDMolSupplier sdf path 0
  • 全局组件和局部组件

    1 全局组件和局部组件的区别 全局组件 只需要在main js中导入一次 整个项目都可以直接使用 在main js中导入 局部组件 用一次 导一次 在用到的地方导入 2 局部组件导入步骤 3部曲 1 导入子组件 import Registe
  • 基于Flask框架的python微博数据分析

    Python 微博数据 博文 分析 项目简介 后端采用Flask框架搭建 通过移动端接口获取数据 数据清洗后采用jieba进行词法分析 通过WordCloud制作词云展示 数据的可视化在以后的版本中会细化 版本V0 0 1功能 能够获取用户
  • 1. redis核心数据结构实战与高性能原理剖析

    分布式缓存技术Redis 1 Redis的五种数据结构 1 1 String 1 2 hash 1 3 列表list 1 4 set 1 5 ZSet 2 Redis的单线程和高性能 3 其他高级命令 3 1 scan 渐进式遍历键 本文是
  • 从零开始学习微服务 -微服务基本概述、微服务案例

    1 SpringCloud概述 1 1 互联网应用架构 1 1 1 单体应用架构 在诞 之初 项目的 户量 数据量规模都 较 项目所有的功能模块都放在一个工程中编码 编译 打包并且部署在一个Tomcat容器中的架构模式就是单体应用架构 这样