• 单体进化微服务:拆分、注册、调用、网关、过滤、治理、分布式事务


    基本介绍

    Spring Cloud 是一个用于构建分布式系统和微服务架构的开发工具包。它提供了一系列的功能和组件,用于解决微服务架构中的常见问题,如服务注册与发现、负载均衡、配置管理、断路器等。本文将介绍如何使用 Spring Cloud 来构建一个简单的微服务架构。

    服务注册与发现:
    在微服务架构中,服务之间的相互调用是通过服务注册与发现来实现的。Spring Cloud 提供了 Eureka、Consul、ZooKeeper 等多种服务注册与发现的实现。我们可以选择其中一种来搭建服务注册中心,并在每个微服务启动时将自己注册到注册中心。

    负载均衡:
    在微服务架构中,负载均衡是将请求分发到多个服务实例上,以实现高可用和扩展性。Spring Cloud 提供了 Ribbon 作为默认的负载均衡解决方案,它可以与服务注册中心集成,自动实现负载均衡的功能。

    配置管理:
    在微服务架构中,配置管理可以帮助我们集中管理各个微服务的配置信息。Spring Cloud 提供了 Config Server 来实现统一的配置管理,将配置文件存储在 Git、SVN 等版本控制系统中,并通过统一的 API 接口提供给微服务使用。

    断路器:
    在微服务架构中,由于服务之间的相互调用,可能会出现某个服务不可用或响应超时的情况。为了保证系统的稳定性,我们可以使用断路器模式来处理这些故障。Spring Cloud 提供了 Hystrix 作为断路器的实现,可以在服务调用发生故障时进行降级或熔断处理。

    在这里插入图片描述

    生产-消费-网关

    将一个服务拆分为生产、消费、网关三个微服务进行基本展示,实现了服务的拆分、注册、调用、网关、过滤,后期实现治理和分布式事务;

    父依赖

    
    <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.0modelVersion>
        <parent>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-parentartifactId>
            <version>2.7.12version>
            <relativePath/>
        parent>
    
    
        <artifactId>springcloud_demoartifactId>
        <packaging>pompackaging>
    
        <modules>
            <module>service_1module>
            <module>service_2module>
    
            <module>gate_servicemodule>
            <module>commonmodule>
            <module>remindermodule>
        modules>
    
        <properties>
            <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
            <org.projectlombok.version>1.18.20org.projectlombok.version>
            <spring-cloud.version>2021.0.3spring-cloud.version>
            <spring-cloud-alibaba.version>2021.0.4.0spring-cloud-alibaba.version>
            <java.version>8java.version>
        properties>
    
        <dependencies>
            
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-starter-configartifactId>
            dependency>
    
            
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-webartifactId>
            dependency>
    
        dependencies>
    
        <dependencyManagement>
            <dependencies>
                
                <dependency>
                    <groupId>com.alibaba.cloudgroupId>
                    <artifactId>spring-cloud-alibaba-dependenciesartifactId>
                    <version>${spring-cloud-alibaba.version}version>
                    <type>pomtype>
                    <scope>importscope>
                dependency>
    
                <dependency>
                    <groupId>org.springframework.cloudgroupId>
                    <artifactId>spring-cloud-dependenciesartifactId>
                    <version>${spring-cloud.version}version>
                    <type>pomtype>
                    <scope>importscope>
                dependency>
    
                
                <dependency>
                    <groupId>org.projectlombokgroupId>
                    <artifactId>lombokartifactId>
                    <version>${org.projectlombok.version}version>
                dependency>
                
                <dependency>
                    <groupId>org.springframework.bootgroupId>
                    <artifactId>spring-boot-starter-testartifactId>
                    <scope>testscope>
                dependency>
    
            dependencies>
        dependencyManagement>
    
    
    
    project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87

    生产者服务

    
    <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>springcloud_demoartifactId>
            <groupId>org.springframework.bootgroupId>
            <version>2.7.12version>
        parent>
        <modelVersion>4.0.0modelVersion>
    
        <artifactId>test_serviceartifactId>
        <dependencies>
    
            
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-webartifactId>
            dependency>
    
            
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-data-redisartifactId>
            dependency>
    
            
    
            
            <dependency>
                <groupId>com.alibaba.cloudgroupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
            dependency>
    
    
        dependencies>
    
    
    project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    properties配置

    server.port=9092
    
    spring.application.name=service2
    
    spring.cloud.nacos.server-addr=lh:8848
    spring.cloud.config.import-check.enabled=false
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    @SpringBootApplication
    public class TestApplication {
        public static void main(String[] args) {
            SpringApplication.run(TestApplication.class, args);
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    基本生产

    @RestController
    @RequestMapping(path = "/hi")
    public class HelloController {
    
        @Resource
        private HelloService helloService;
    
    
        @RequestMapping(path = "/sy", method = RequestMethod.GET)
        public String sy(){
            // 1.根据服务名称,拉取服务的实例列表
            helloService.sayHi();
            return "service-2 say hi";
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    消费者服务

    
    <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>springcloud_demoartifactId>
            <groupId>org.springframework.bootgroupId>
            <version>2.7.12version>
        parent>
        <modelVersion>4.0.0modelVersion>
    
        <artifactId>test_2artifactId>
    
        <dependencies>
    
            
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-webartifactId>
            dependency>
    
            
    
            
            <dependency>
                <groupId>com.alibaba.cloudgroupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
            dependency>
            <dependency>
                <groupId>cn.hutoolgroupId>
                <artifactId>hutool-allartifactId>
                <version>5.8.11version>
                <scope>compilescope>
            dependency>
    
    
            
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-starter-openfeignartifactId>
            dependency>
            
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-starter-loadbalancerartifactId>
            dependency>
            
            <dependency>
                <groupId>io.github.openfeigngroupId>
                <artifactId>feign-okhttpartifactId>
            dependency>
    
        dependencies>
    
    project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    server.port=9091
    
    spring.application.name=service1
    
    spring.cloud.nacos.server-addr=lh:8848
    spring.cloud.config.import-check.enabled=false
    
    
    feign.okhttp.enabled=true
    
    logging.level.com.com.han=debug
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    import com.han.config.DefaultFeignConfig;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    
    @EnableFeignClients(basePackages = "com.han.remote", defaultConfiguration = DefaultFeignConfig.class)
    @SpringBootApplication
    public class Test2Application {
        public static void main(String[] args) {
            SpringApplication.run(Test2Application.class, args);
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    配置类

    import feign.Logger;
    import org.springframework.context.annotation.Bean;
    
    public class DefaultFeignConfig {
    
        @Bean
        public Logger.Level feignLogLevel(){
            return Logger.Level.FULL;
        }
    }
    
    ``@FeignClient(value = "service2")
    public interface Service2Client {
    
        @RequestMapping(method = RequestMethod.GET, path = "/hi/sy")
        String getHi();
    
    }
    
    
    
    
    ```java
    @Configuration
    public class AppConfig {
    
        @Bean
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    controller

    
    @RestController
    @RequestMapping(path = "/hello")
    public class HelloController {
    
        @Resource
        private HelloService helloService;
    
        @Resource
        private Service2Client service2Client;
    
    
        @RequestMapping(method = RequestMethod.GET, path = "/sy")
        public void sy(){
            // 1.根据服务名称,拉取服务的实例列表
            System.out.println(service2Client.getHi());
            helloService.sayHi();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    消费service

    @Service
    public class HelloServiceImpl implements HelloService {
    
        private final DiscoveryClient discoveryClient;
    
        @Resource
        private RestTemplate restTemplate;
    
        @Resource
        private Service2Client service2Client;
    
        public HelloServiceImpl(DiscoveryClient discoveryClient) {
            this.discoveryClient = discoveryClient;
        }
    
        @Override
        public void sayHi() {
            System.out.println("service-1 say hi");
            System.out.println(service2Client.getHi());
        }
    
    
        public void sayHiByRestTemplate() {
            System.out.println("service-1 say hi");
    
            List<ServiceInstance> instances = discoveryClient.getInstances("service_2");
            // 2.负载均衡,挑选一个实例
            ServiceInstance instance = instances.get(RandomUtil.randomInt(instances.size()));
            // 3.获取实例的IP和端口
            ResponseEntity<String> response = restTemplate.exchange(
                    instance.getUri() + "/hi",
                    HttpMethod.GET,
                    null,
                    new ParameterizedTypeReference<String>() {
                    },
                    new Object());
            System.out.println(response.getBody());
            System.out.println(response);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    网关服务

    
    <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>springcloud_demoartifactId>
            <groupId>org.springframework.bootgroupId>
            <version>2.7.12version>
        parent>
        <modelVersion>4.0.0modelVersion>
    
        <artifactId>gate_serviceartifactId>
        <dependencies>
            
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-starter-gatewayartifactId>
            dependency>
    
            
            <dependency>
                <groupId>com.alibaba.cloudgroupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
            dependency>
    
    
            
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-starter-loadbalancerartifactId>
            dependency>
    
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>commonartifactId>
                <version>2.7.12version>
            dependency>
        dependencies>
    
    project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    server.port=9090
    
    spring.application.name=gateway
    
    spring.cloud.nacos.server-addr=lh:8848
    spring.cloud.config.import-check.enabled=false
    
    logging.level.com.com.han=debug
    logging.pattern.dateformat=HH:mm:ss:SSS
    logging.file.path="logs/${spring.application.name}"
    
    spring.cloud.gateway.routes[0].id=service1
    spring.cloud.gateway.routes[0].uri=lb://service1
    spring.cloud.gateway.routes[0].predicates[0]=Path=/hello/**,/user/**
    spring.cloud.gateway.routes[0].filters[0]=PrintAny
    
    
    
    spring.cloud.gateway.routes[1].id=service2
    spring.cloud.gateway.routes[1].uri=lb://service2
    spring.cloud.gateway.routes[1].predicates[0]=Path=/hi/**
    
    spring.main.web-application-type=reactive
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    @SpringBootApplication
    public class GateApplication {
        public static void main(String[] args) {
            SpringApplication.run(GateApplication.class, args);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    
    @Component
    public class PrintAnyGatewayFilterFactory extends AbstractGatewayFilterFactory<Object> {
        @Override
        public GatewayFilter apply(Object config) {
            return new GatewayFilter() {
                @Override
                public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                    // 获取请求
                    ServerHttpRequest request = exchange.getRequest();
                    // 编写过滤器逻辑
                    System.out.println("过滤器执行了");
                    // 放行
                    return chain.filter(exchange);
                }
            };
        }
    }
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    common服务

    
    <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>springcloud_demoartifactId>
            <groupId>org.springframework.bootgroupId>
            <version>2.7.12version>
        parent>
        <modelVersion>4.0.0modelVersion>
    
        <artifactId>commonartifactId>
    
    
        <dependencies>
            
            <dependency>
                <groupId>org.projectlombokgroupId>
                <artifactId>lombokartifactId>
                <version>1.18.20version>
                <scope>providedscope>
            dependency>
    
            <dependency>
                <groupId>cn.hutoolgroupId>
                <artifactId>hutool-allartifactId>
                <version>5.8.11version>
                <scope>compilescope>
            dependency>
        dependencies>
    
    project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    public class UserInfoInterceptor implements HandlerInterceptor {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            // 1.获取请求头中的用户
            String userInfo = request.getHeader("user-info");
            // 2.判断是否为空,不为空,存入Usercontext
            if (StrUtil.isNotBlank(userInfo)) {
    
    
            }
            // 3.放行
            return true;
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception{
    
            // 清除用户
    //        UserContext.removeUser();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    package com.han.utils;
    
    
    import lombok.Data;
    
    @Data
    public class Result<T> {
    
        //状态码
        private Integer code;
        //信息
        private String message;
        //数据
        private T data;
    
        //构造私有化
        private Result() { }
    
        //设置数据,返回对象的方法
        public static<T> Result<T> build(T data,Integer code,String message) {
            //创建Resullt对象,设置值,返回对象
            Result<T> result = new Result<>();
            //判断返回结果中是否需要数据
            if(data != null) {
                //设置数据到result对象
                result.setData(data);
            }
            //设置其他值
            result.setCode(code);
            result.setMessage(message);
            //返回设置值之后的对象
            return result;
        }
    
    
        //设置数据,返回对象的方法
        public static<T> Result<T> build(T data,ResultCodeEnum resultCodeEnum) {
            //创建Resullt对象,设置值,返回对象
            Result<T> result = new Result<>();
            //判断返回结果中是否需要数据
            if(data != null) {
                //设置数据到result对象
                result.setData(data);
            }
            //设置其他值
            result.setCode(resultCodeEnum.getCode());
            result.setMessage(resultCodeEnum.getMessage());
            //返回设置值之后的对象
            return result;
        }
    
        //成功的方法
        public static<T> Result<T> ok(T data) {
            Result<T> result = build(data, ResultCodeEnum.SUCCESS);
            return result;
        }
    
        //失败的方法
        public static<T> Result<T> fail(T data) {
            return build(data,ResultCodeEnum.FAIL);
        }
    
        public static<T> Result<T> success(T data){
            return build(data, ResultCodeEnum.MY_CONDITION);
        }
    
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    /**
     * 统一返回结果状态信息类
     *
     */
    @Getter
    public enum ResultCodeEnum {
    
        SUCCESS(200,"成功"),
        FAIL(201, "失败"),
    
        MY_CONDITION(666, "JUST 6"),
        ;
    
        private Integer code;
    
        private String message;
    
        private ResultCodeEnum(Integer code, String message) {
            this.code = code;
            this.message = message;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    感想

    框架的引入,让我们可以只需要导包就可以完成95%的工作;
    但是如何抛开框架,我们是否可以自己完成spring、springcloud这些框架的基本功能那?
    技术的提升不会仅仅是使用这些api接口,我们后面会尝试自己设计一些框架去替代

  • 相关阅读:
    《Ai企业知识库》-模型实践-rasa开源学习框架-搭建简易机器人-环境准备(针对windows)-02
    Puppeteer记录操作过程及优秀的开源插件(五)
    Midjourney竞品Leap免费试用; Google 刚刚发布10门独立AI课程
    ipv6地址概述——带你了解ipv6与ipv4的不同
    Qt调用工业相机之海康威视相机SDK【回调取流的使用】(完整版)
    回收站永久删除了如何恢复正常?
    WMware Tools安装失败segmentation fault解决方法
    Android学习笔记 69. 文本和滚动视图
    【脉冲通信】用于空间应用的飞秒脉冲通信的符号误码率模型研究(Matlab代码实现)
    日常Bug排查-MVCC和for update混用导致读数据不一致
  • 原文地址:https://blog.csdn.net/futurn_hero/article/details/134531703