从0到1搭建微服务框架

目录

1.技术栈:

2.模块介绍:

3.关键代码讲解

3.1基础公共模块(common)依赖:

3.3授权模块(auth)依赖:

3.4授权模块核心配置类(AuthrizatonConfig):

3.4  SecurityConfig.java

 3.5 bootstrap的核心配置文件(其他服务配置类似这个):

3.6nacos上面的配置文件如auth-dev.yaml

3.7 consumer-dev.yaml

3.8 gateway-dev.yaml:

3.9mq-dev.yaml:

4.授权认证模块演示:

4.1获取到授权码:

4.2 通过postman请求获取access_token

4.2测试通过access_token访问资源:

4.3 无token携带的时候,访问服务资源

4.4 在指定模块添加配置类(ResourceServerConfig):

5.nacos相关配置,以及服务注册情况

5.1nacos配置显示:

5.2 nacos上服务显示:


1.技术栈:

SpringCloud  微服务基础架构

1.1.nacos  用于服务的注册,作为注册中心,同时也利用了nacos的热更新特点,使用nacos作为配置中心。

1.2.Mysql 主要用了mqsql8.0版本,mysql作为关系型数据库的存储

1.3.MybatisPlus 主要使用了MybatisPlu实现对mysql数据库的操作,实现增删改查。

1.4.Oauth2.0 主要使用ouath2.0实现微服务的授权认证登录。

1.5.消息队列 rabbitMQ,应对物联网设备数据并发的中间件,对设备数据进行排队处理

1.6.emqx 主要用于设备的mqtt连接

2.模块介绍:

2.1.auth模块:主要是集成了数据库的连接,以及ouath 的授权认证功能。

2.2.common模块:作为公共模块,为其他模块提供基础类以及公共依赖,降低代码的耦合度

2.3.consumer模块:消费者模块,主要用于消费rabbitmq产生的数据信息。

2.4.mq模块:主要用于设备处理设备上报的数据。

2.5.gateway模块:主要作为接口请求统一入口,做链路追踪,以及拦截请求。

2.6.system模块:后台管理平台业务开发模块。

代码结构示意图:

3.关键代码讲解

3.1基础公共模块(common)依赖:

<?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.3.2.RELEASE</version><!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>common</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>common</name>
    <description>Demo project for Spring Boot</description>
    <url/>
    <licenses>
        <license/>
    </licenses>
    <developers>
        <developer/>
    </developers>
    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>
    <properties>
        <java.version>8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Hoxton.SR8</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
            <version>3.0.0</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>

        <!-- mybatis-plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.2</version>
        </dependency>

        <!-- mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
          <!--阿里巴巴数据库连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.8</version>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </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>
            </plugin>
        </plugins>
    </build>

</project>

3.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 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.3.2.RELEASE</version>
     <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>gateway</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>gateway</name>
    <description>Demo project for Spring Boot</description>
    <url/>
    <licenses>
        <license/>
    </licenses>
    <developers>
        <developer/>
    </developers>
    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>
    <properties>
        <java.version>8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>common</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-web</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
      <!--  网关配置-->


        <!--网关发现服务后,进行负载均衡的转发调用-->
      <!--  <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
            <version>3.1.2</version>
        </dependency>-->
        <!--网关核心依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
            <version>2.2.10.RELEASE</version>
            <exclusions>
                <exclusion>
                    <groupId>io.projectreactor.netty</groupId>
                    <artifactId>reactor-netty</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--版本冲突报错指定reactor-netty、spring-webflux版本-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webflux</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>io.projectreactor.netty</groupId>
            <artifactId>reactor-netty</artifactId>
            <version>0.9.14.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </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>
            </plugin>
        </plugins>
    </build>

</project>

3.3授权模块(auth)依赖:

<?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.3.2.RELEASE</version>
       <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>auth</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>auth</name>
    <description>Demo project for Spring Boot</description>
    <url/>
    <licenses>
        <license/>
    </licenses>
    <developers>
        <developer/>
    </developers>
    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>




    <properties>
        <java.version>8</java.version>
    </properties>
    <dependencies>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>



        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-security</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

     <!--   引入公共模块-->
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>common</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
     <!--引入数据库模块-->


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </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>
            </plugin>
        </plugins>
    </build>

</project>

3.4授权模块核心配置类(AuthrizatonConfig):

package com.example.auth.config;

import org.apache.http.protocol.HTTP;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
import org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
//访问授权地址获取授权码 http://localhost:8063/oauth/authorize?client_id=test&response_type=code&scope=all&redirect_uri=http://www.baidu.com
@Configuration
@EnableAuthorizationServer
public class AuthrizatonConfig  extends AuthorizationServerConfigurerAdapter {
    @Autowired
    private ClientDetailsService clientDetailsService;
    @Autowired
    private AuthenticationManager authenticationManager;
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
       security//开启tokenkey权限访问
               .tokenKeyAccess("permitAll()")
               .checkTokenAccess("permitAll()")
               .allowFormAuthenticationForClients();
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
      clients.inMemory()
              .withClient("test")
              .secret(new BCryptPasswordEncoder().encode("123456"))
              .resourceIds("auth","mq","gateway")
              .authorizedGrantTypes("authorization_code","password","client_credentials","implicit","refresh_token")
              .scopes("all")
              .autoApprove(false)
              .redirectUris("http://www.baidu.com");
    }

    /**
     * 令牌存储策略
     * @return
     */
    @Bean
    public TokenStore tokenStore(){
        return new InMemoryTokenStore();
    }

    @Bean
    public AuthorizationServerTokenServices tokenServices(){
        DefaultTokenServices services = new DefaultTokenServices();
        services.setSupportRefreshToken(true);
        services.setTokenStore(tokenStore());
        services.setAccessTokenValiditySeconds(60*60*60*2);
        services.setRefreshTokenValiditySeconds(60*60*24*3);
        return services;
    }

    public AuthorizationCodeServices authorizationCodeServices(){
        return  new InMemoryAuthorizationCodeServices();
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authorizationCodeServices(authorizationCodeServices())
                .authenticationManager(authenticationManager)
                .tokenServices(tokenServices())
                .allowedTokenEndpointRequestMethods(HttpMethod.POST);

    }
}

3.4  SecurityConfig.java

package com.example.auth.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
public class SecurityConfig  extends WebSecurityConfigurerAdapter {

    /**
     * 密码加密
     * @return
     */
    @Bean
    PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.inMemoryAuthentication()
                .withUser("admin")
                .password(new BCryptPasswordEncoder()
                        .encode("123456"))
                .roles("admin");

    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
      //允许表单登录
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginProcessingUrl("/login")
                .permitAll()
                .and()
                .csrf()
                .disable();
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

 3.5 bootstrap的核心配置文件(其他服务配置类似这个):

server:
  port: 8061
spring:
  application:
    name: auth
  profiles:
    active:
      dev
  cloud:
    nacos:
      config:
        file-extension: yaml
        #启用配置热更新功能
        refresh-enabled: true
        prefix: auth
      server-addr: 192.168.1.24:8848
      discovery:
        instance-enabled: true
        server-addr: 192.168.1.24:8848
        cluster-name: auth
        service: auth-service

3.6nacos上面的配置文件如auth-dev.yaml

spring:
    datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/auth?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&nullCatalogMeansCurrent=true
        username: root
        password: Root@123
        type: com.alibaba.druid.pool.DruidDataSource
        druid:
            initial-size: 5
            min-idle: 1
            max-active: 10
            max-wait: 60000
            validation-query: SELECT 1 FROM DUAL
            test-on-borrow: false
            test-on-return: false
            test-while-idle: true
            time-between-eviction-runs-millis: 60000
mysql:
 driver: com.mysql.jdbc.driver

3.7 consumer-dev.yaml

spring:
    datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/auth?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&nullCatalogMeansCurrent=true
        username: root
        password: Root@123
        type: com.alibaba.druid.pool.DruidDataSource
        druid:
            initial-size: 5
            min-idle: 1
            max-active: 10
            max-wait: 60000
            validation-query: SELECT 1 FROM DUAL
            test-on-borrow: false
            test-on-return: false
            test-while-idle: true
            time-between-eviction-runs-millis: 60000

3.8 gateway-dev.yaml:

spring:
  datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/gateway?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&nullCatalogMeansCurrent=true
        username: root
        password: Root@123
        type: com.alibaba.druid.pool.DruidDataSource
        druid:
            initial-size: 5
            min-idle: 1
            max-active: 10
            max-wait: 60000
            validation-query: SELECT 1 FROM DUAL
            test-on-borrow: false
            test-on-return: false
            test-while-idle: true
            time-between-eviction-runs-millis: 60000
  cloud:
    gateway:
      globalcors: # 全局的跨域配置
      # 解决options请求被拦截问题
        add-to-simple-url-handler-mapping: true 
               # options请求 就是一种询问服务器是否浏览器可以跨域的请求
               # 如果每次跨域都有询问服务器是否浏览器可以跨域对性能也是损耗
               # 可以配置本次跨域检测的有效期maxAge
               # 在maxAge设置的时间范围内,不去询问,统统允许跨域
        corsConfigurations:
          '[/**]':
            allowedOrigins:   # 允许哪些网站的跨域请求 
              - "http://localhost:8061"
            allowedMethods:   # 允许的跨域ajax的请求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*"  # 允许在请求中携带的头信息
            allowCredentials: true # 允许在请求中携带cookie
            maxAge: 360000    # 本次跨域检测的有效期(单位毫秒)
      discovery:
        locator:
          enabled: true
      routes:
         #路由微服务名称,
        - id: auth-service            
        #路由目标微服务 lb代表负载均衡协议
          uri: lb://auth-service        
          #以请求路径做判断,只要符合匹配规则的请求就会被转发到上面信息对应的微服务中去  #路由断言,判断是否符合规则,符合规则路由到目标 
          predicates:                  
            - Path=/auth/**,/search/**            
                                             
        - id: consumer-service
          uri: lb://consumer-service
          predicates:
            - Path=/consumer/**
        - id: system-service
          uri: lb://system-service
          predicates:
            - Path=/system/**,/addresses/**
        - id: mq-service
          uri: lb://mq-service
          predicates:
            - Path=/mq/**
          #filters:                       # 过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改# 转发之前去掉1层路径
            #- StripPrefix=1              
      default-filters:            #默认过滤器,对请求进行处理
      #在请求头中添加信息,前键后值。
        - AddRequestHeader=headerName, project is well 

3.9mq-dev.yaml:

mq: dsswaz
spring:
    datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/auth?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&nullCatalogMeansCurrent=true
        username: root
        password: Root@123
        type: com.alibaba.druid.pool.DruidDataSource
        druid:
            initial-size: 5
            min-idle: 1
            max-active: 10
            max-wait: 60000
            validation-query: SELECT 1 FROM DUAL
            test-on-borrow: false
            test-on-return: false
            test-while-idle: true
            time-between-eviction-runs-millis: 60000

4.授权认证模块演示:

通过访问http://localhost:8061/oauth/authorize?client_id=test&response_type=code&scope=all&redirect_uri=http://www.baidu.com

地址获取code  输入账户 admin  密码:123456

4.1获取到授权码:

4.2 通过postman请求获取access_token

4.2测试通过access_token访问资源:

4.3 无token携带的时候,访问服务资源

4.4 在指定模块添加配置类(ResourceServerConfig):

package com.example.mq.config;


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.RemoteTokenServices;

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Bean
    public RemoteTokenServices tokenServices(){

        RemoteTokenServices tokenServices = new RemoteTokenServices();
        tokenServices.setCheckTokenEndpointUrl("http://localhost:8061/oauth/check_token");
        tokenServices.setClientId("test");
        tokenServices.setClientSecret("123456");
        return tokenServices;
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
       resources.resourceId("mq")
               .tokenServices(tokenServices());
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
      http.authorizeRequests()
              .antMatchers("/**")
              .access("#oauth2.hasScope('all')")
              .anyRequest()
              .authenticated();
    }
}

5.nacos相关配置,以及服务注册情况

5.1nacos配置显示:

5.2 nacos上服务显示:

通过以上配置完成微服务框架的简单auth2.0授权配置。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

视频编解码从H.264到H.266:浅析GB28181安防视频汇聚EasyCVR视频压缩技术

随着信息技术的飞速发展&#xff0c;视频编解码技术也在不断革新&#xff0c;以适应高清、超高清甚至8K视频时代的到来。视频编解码技术作为数字多媒体领域的核心技术之一&#xff0c;也在不断地演进和革新。从早期的H.261到现在的H.265、H.266&#xff0c;每一次技术的升级都极…

便携式气象站:科技助力,气象观测的新选择

在气象观测领域&#xff0c;便携式气象站不仅安装方便、操作简单&#xff0c;而且功能齐全、性能稳定&#xff0c;为气象观测带来了极大的便利。 首先&#xff0c;便携式气象站的便携性&#xff0c;与传统的气象站相比&#xff0c;它不需要复杂的安装过程和固定的设备基础&…

收银系统源码-千呼新零售2.0【移动管理端】

千呼新零售2.0系统是零售行业连锁店一体化收银系统&#xff0c;包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体&#xff0c;线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货、宠物等连锁店使用。 详细介绍请…

昂首资本实例使用价格行为策略,交易翻倍一点都不难

交易翻倍难吗&#xff1f;当Anzo Capital昂首资本使用价格行为策略进行交易时&#xff0c;发现一点都不难&#xff0c;以下是使用价格行为策略的实例分享&#xff1a; 1. 在初次交易信号出现时&#xff0c;推荐在1.00429价位入场&#xff0c;将止损设于1.04399&#xff0c;止盈…

微信小程序的在线客服系统源码 附带完整的源代码包以及搭建部署教程

系统概述 微信小程序的在线客服系统源码是一套专门为微信小程序开发的客服解决方案。它通过与微信小程序的紧密集成&#xff0c;为用户提供了便捷、高效的客服沟通渠道。该系统源码采用先进的技术架构&#xff0c;具备良好的稳定性和扩展性&#xff0c;能够满足不同规模企业的…

【数据结构】C语言实现二叉树的基本操作——二叉树的层次遍历、求深度、求结点数……

C语言实现二叉树的基本操作 导读一、层次遍历1.1 算法思路1.2 算法实现1.2.1 存储结构的选择1.2.2 函数的三要素1.2.3 函数的实现 1.3 小结 二、求二叉树的深度2.1 层序遍历2.2 分治思想——递归 三、 求二叉树的结点数3.1 求二叉树的结点总数3.1.1 层序遍历3.1.2 分治思想——…

Cherno 游戏引擎笔记 (45~60)

有几个部分的笔记以图片形式呈现&#xff08;如果没找到文本可以查看是否遗漏了图片笔记&#xff09; My Github REPO(GitHub - JJJJJJJustin/Nut: The game_engine which learned from Cherno) 源码笔记&#xff0c;希望帮到你 :-} ---Shader Library&#xff08;着色器库&…

[机器学习]-4 Transformer介绍和ChatGPT本质

Transformer Transformer是由Vaswani等人在2017年提出的一种深度学习模型架构&#xff0c;最初用于自然语言处理&#xff08;NLP&#xff09;任务&#xff0c;特别是机器翻译。Transformer通过自注意机制和完全基于注意力的架构&#xff0c;核心思想是通过注意力来捕捉输入序列…

什么是接口测试,我们如何实现接口测试?

1. 什么是接口测试 顾名思义&#xff0c;接口测试是对系统或组件之间的接口进行测试&#xff0c;主要是校验数据的交换&#xff0c;传递和控制管理过程&#xff0c;以及相互逻辑依赖关系。其中接口协议分为HTTP,WebService,Dubbo,Thrift,Socket等类型&#xff0c;测试类型又主…

oracle plsql如何debug触发器

进入测试窗口 Test Window 写以下代码 declarebegininsert into tableA values();end; 如果tableA有insert触发器&#xff0c;插入数据的时候&#xff0c;就能进入触发器的代码里面

【区块链+基础设施】区块链服务网络 BSN | FISCO BCOS应用案例

BSN&#xff08;Blockchain-based Service Network&#xff0c;区块链服务网络&#xff09;是一个跨云服务、跨门户、跨底层框架&#xff0c;用于部 署和运行各类区块链应用的全球性基础设施网络&#xff0c;旨在为开发者提供低成本和技术互通的区块链一站式服务。 2019 年 12…

Android LayoutInflater 深度解析

在 Android 开发中&#xff0c;LayoutInflater 是一个非常重要的工具。它允许我们从 XML 布局文件中动态地创建 View 对象&#xff0c;从而使得 UI 的创建和管理更加灵活。本文将深入解析 android.view.LayoutInflater&#xff0c;包括它的基本用法、常见问题以及高级用法。 什…

stm32学习笔记---DMA直接存储器存取(代码部分)DMA数据转运/DMA+AD多通道

目录 第一个代码&#xff1a;DMA数据转运 扩展知识 DMA的配置步骤 DMA的库函数 DMA_DeInit DMA初始化和DMA结构体初始化函数 DMA_Cmd DMA_ITConfig DMA_SetCurrDataCounter DMA_GetCurrDataCounter 四个获取标志位状态函数 代码实现 MyDMA.c 第一步&#xff0c;开…

网站提示不安全怎么办

当您访问一个网站时&#xff0c;如果浏览器提示该网站不安全&#xff0c;这通常意味着以下几个问题之一&#xff0c;以及相应的解决办法&#xff1a; 一、未启用HTTPS协议&#xff1a; 解决方法&#xff1a;确保网站启用了HTTPS协议。这意味着您需要为您的网站部署一个有效的…

鸿蒙:this传递参数到子组件中无法实现

this指代当前组件的某个变量&#xff0c;当把这个变量当作参数传递给子组件时&#xff0c;子组件中没有这个变量&#xff0c;属于使用不了这个变量 解决方法&#xff1a;在变量后面加.bind(this)将当前组件的变量一起绑定过去

电脑ip地址在哪里看?3个方法全解析,找到地址不迷路

ip地址&#xff0c;就像网络世界中的身份证&#xff0c;是每个设备在网络上的唯一标识。无论是浏览网页、在线聊天还是远程办公&#xff0c;都离不开它的指引。那么&#xff0c;电脑ip地址在哪里看&#xff1f;别担心&#xff0c;本文将带你踏上寻找ip地址的冒险之旅&#xff0…

#HDC2024 心得分享#主题演讲学习-加入鸿蒙生态正当时

一、主题演讲学习心得 通过本次主题演讲的聆听与学习&#xff0c;我们在猜出中和不太确定的相关内容纷纷呈现。比如鸿蒙内核与HarmonyOS Next获得行业内最高等级的安全认证&#xff1b;盘古大模型、小艺智能体、意图理解与分发框架等构筑的AI、AIGC能力对HarmonyOS Next及原生…

ABeam×StartUp | ABeam德硕中国新创部门拜访通用机器人初创公司 :逐际动力,就具身智能机器人的发展展开交流

近日&#xff0c;ABeam中国新创部门有幸拜访了深圳逐际动力科技有限公司&#xff08;以下简称&#xff1a;逐际动力&#xff09;。作为一家通用机器人公司&#xff0c;其在人形机器人、四轮足机器人等领域具有深厚的学术与技术储备。 现场合影 左&#xff1a;ABeam中国新创部门…

Golang | Leetcode Golang题解之第202题快乐数

题目&#xff1a; 题解&#xff1a; func isHappy(n int) bool {cycle : map[int]bool{4: true, 6: true, 37: true, 58: true, 89: true, 145: true, 42: true, 20: true}for n ! 1 && !cycle[n] {n step(n)}return n 1 }func step(n int) int {sum : 0for n > …

交友系统定制版源码| 相亲交友小程序源码全开源可二开_打造独特的社交交友系统

交友系统源码的实现涉及到多个方面&#xff0c;包括前端页面设计、后端逻辑处理、数据库设计以及用户交互等。以下是一个简单的交友系统源码实现的基本框架和关键步骤: 1.数据库设计:用户表:存储用户基本信息&#xff0c;如用户ID、用户名、密码、头像、性别、年龄、地理位置等…