阶段性回顾

阶段笔记

Day01

1.请你简单介绍下软件开发中系统架构的演变?

单一应用—>垂直拆分—>分布式服务—>服务治理(SOA)—>微服务架构

2.远程调用的方式有几种? 他们的区别如何?如何选择?

远程调用有两种方式:

  1. RPC(Remote Produce Call)即远程过程调用;
  2. Http:一种基于TCP、规定了数据传输格式的网络传输协议;

两种方式的区别:

  1. RPC并没有规定数据传输格式,这个格式可以任意指定,不同的RPC协议,数据格式不一定相同;
  2. Http中定义了资源定位的路径,RPC中并不需要;
  3. RPC需要满足像调用本地服务一样调用远程服务,也就是对调用过程在API层面进行封装。Http协议没有这样的要求,因此请求、响应等细节需要我们自己去实现。

优点:RPC方式更加透明,对用户更方便。HTTP方式更灵活,没有规定API和语言,跨语言、跨平台;

缺点:RPC方式需要在API层面进行封装,限制了开发的语言环境;

如何选择:

  • 如果对效率要求更高,并且开发过程使用统一的技术栈,用RPC
  • 如果需要更加灵活,跨语言、跨平台,用HTTP

3.SpringCloud是什么?

Spring Cloud是一系列框架的有序集合。他利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、熔断器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。

4.简述SpringCloud和SpringBoot的关系?

  1. Spring Boot是Spring的一套快速配置脚手架,可以基于Spring Boot快速可开发单个微服务,Spring Cloud是一个基于Spring Boot实现的云应用开发工具;
  2. Spring Boot专注于快速方便开发单个微服务个体,Spring Cloud关注全局的微服务治理框架,它将Spring Boot开发的一个个微服务整合并管理起来,为各个服务之间提供服务发现、负载均衡、断路器、路由、配置管理、微代理、消息总线、全局锁、分布式会话等集成服务;
  3. Spring Boot可以离开Spring Cloud独立使用开发项目,但是Spring Cloud离不开Spring Boot,属于依赖关系。

5.SpringCloudNetflix分布式解决方案中主要框架有哪些?

Spring Cloud Netflix分布式解决方案中主要框架有:

  • 服务发现——Netflix Eureka
  • 服务调用——Netflix Feign
  • 熔断器——Netflix Hystrix
  • 服务网关——Netflix Zuul
  • 分布式配置——Spring Cloud Config
  • 消息总线——Spring Cloud Bus

6.请简单介绍下springCloudAlibaba?

Spring Cloud Alibaba也是一套微服务解决方案,包含开发分布式应用微服务的必需组件,方便开发者通过Spring Cloud编程模型轻松使用这些组件来开发分布式应用服务,是阿里巴巴开源中间件与Spring Cloud体系的融合。

7.阿里开源组件有哪些?功能是什么?

阿里开源组件及功能如下:

  • Nacos:一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台;

  • Sentinel:把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性;

  • RocketMQ:开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务;

  • Dubbo:一款高性能 Java RPC 框架;

  • Seata:一个易于使用的高性能微服务分布式事务解决方案;

  • Arthas:开源的Java动态追踪工具,基于字节码增强技术,功能非常强大。

8.什么是nacos? 为什么要使用nacos? nacos可以干什么?

什么是Nacos

Nacos 是阿里巴巴推出来的一个新开源项目,这是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。

为什么要使用Nacos

Nacos更加强大,它可以与 Spring, Spring BootSpring Cloud 集成,并能代替 Spring Cloud EurekaSpring Cloud Config。通过Nacos Serverspring-cloud-starter-alibaba-nacos-config实现配置的动态变更。通过Nacos Serverspring-cloud-starter-alibaba-nacos-discovery实现服务的注册与发现。

Nacos可以干什么:

  1. 服务发现和服务健康监测;
  2. 动态配置付服务;
  3. 动态DNS服务;
  4. 服务及其元数据管理

9.简单说说如何下载安装启动nacos?

下载:通过源码和发行包两种方式来获取 Nacos。可以从https://github.com/alibaba/nacos/releases下载nacos-server-$version.zip 包。
启动:

  • linux系统:将Nacos压缩包解压后,进入Nacos目录下的bin目录,然后输入 ./startup.sh -m standalone启动。
  • window系统:将Nacos压缩包解压后,同时按住win+R,然后输入cmd打开命令行窗口,键入Nacos的路径,然后进入bin目录,输入startup.cmd -m standalone启动。

10.如何发布服务到nacos?需要哪些配置?

首先创建两个Spring Boot工程生产者nacos-provider和消费者nacos-consumer,然后将生产者和消费者注册到nacos注册中心,主要分三步:1、添加依赖 2、在application.yml中配置nacos的服务名及服务地址;3、通过Spring Cloud原生注解开启服务注册发现功能;

需要的配置有:

  1. 添加依赖:spring-cloud-starter-alibaba-nacos-discoveryspringCloud

    
    <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.0modelVersion>
        <parent>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-parentartifactId>
            <version>2.3.9.RELEASEversion>
            <relativePath/> 
        parent>
        <groupId>com.offcngroupId>
        <artifactId>nacos-providerartifactId>
        <version>1.0version>
        <name>nacos-providername>
        <description>Demo project for Spring Bootdescription>
        <properties>
            <java.version>1.8java.version>
        properties>
        
        <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>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-testartifactId>
                <scope>testscope>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintagegroupId>
                        <artifactId>junit-vintage-engineartifactId>
                    exclusion>
                exclusions>
            dependency>
        dependencies>
    
        
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloudgroupId>
                    <artifactId>spring-cloud-dependenciesartifactId>
                    <version>Hoxton.SR2version>
                    <type>pomtype>
                    <scope>importscope>
                dependency>
                <dependency>
                    <groupId>com.alibaba.cloudgroupId>
                    <artifactId>spring-cloud-alibaba-dependenciesartifactId>
                    <version>2.1.0.RELEASEversion>
                    <type>pomtype>
                    <scope>importscope>
                dependency>
            dependencies>
        dependencyManagement>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.bootgroupId>
                    <artifactId>spring-boot-maven-pluginartifactId>
                plugin>
            plugins>
        build>
    
    project>
    
  2. application.yml中配置nacos服务地址和应用名

    spring:
      application:
        name: nacos-provider
      cloud:
        nacos:
          discovery:
            server-addr: 127.0.0.1:8848
    
  3. 在引导类中添加@EnableDiscoveryClient注解

11.消费者如何通过Feign远程调用服务?

  1. 首先在项目中引入feign依赖

    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-openfeignartifactId>
    dependency>
    
  2. 在消费者服务启动类上添加@EnableFeignClients注解:

  3. 创建feign接口并编写如下内容

    @FeignClient("nacos-provider")
    public interface Feign {
    	@RequestMapping("hello")
    	public String hello();
    }
    
  4. 最后在Controller中使用feignClient

    @RestController
    public class ConsumerController {
    @Autowired
    private Feign feign;
    
    @GetMapping("hi")
    public String hi() {
        return this.feign.hello();
      }
    }
    

12.简述nacos配置中心可以做什么?

在系统开发过程中,开发者通常会将一些需要变更的参数、变量等从代码中分离出来独立管理,以独立的配置文件的形式存在。目的是让静态的系统工件或者交付物(如 WAR,JAR 包等)更好地和实际的物理运行环境进行适配。配置管理一般包含在系统部署的过程中,由系统管理员或者运维人员完成。配置变更是调整系统运行时的行为的有效手段。

nacos配置中心可以做系统配置的集中管理(编辑、存储、分发)、动态更新不重启、回滚配置(变更管理、历史版本管理、变更审计)等所有与配置相关的活动。

命名空间切换环境:在实际开发中,通常有多套不同的环境(默认只有public),那么这个时候可以根据指定的环境来创建不同的 namespce,例如,开发、测试和生产三个不同的环境,那么使用一套nacos集群可以分别建以下三个不同的namespace。以此来实现多环境的隔离。

分组区分环境:在实际开发中,除了不同的环境外。不同的微服务或者业务功能,可能有不同的redismysql数据库。区分不同的环境我们使用名称空间(namespace),区分不同的微服务或功能,使用分组(group)。也可以反过来使用,名称空间和分组只是为了更好的区分配置,提供的两个维度而已。

Day02

1.请简单叙述下SpringCloudGateway是什么?有什么功能?

SpringCloudGateway是API网关,是介于客户端和服务器端之间的中间层,所有的外部请求都会先经过API网关这一层。也就是说,API的实现方面更多的考虑业务逻辑,而安全、性能、监控可以交由 API 网关来做,这样既提高业务灵活性又不缺安全性。

功能:

  • 负载均衡
  • 熔断降级
  • 统一鉴权
  • 请求过滤
  • 路径重写
  • 限流保护

2.如何快速搭建一个网关Gateway?需要进行哪些配置?

  1. 使用SpringBoot创建网关module,选择Gateway

  2. 引入依赖

    
    <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.0modelVersion>
        <parent>
             <groupId>org.springframework.bootgroupId>
             <artifactId>spring-boot-starter-parentartifactId>
             <version>2.3.9.RELEASEversion>
             <relativePath/> 
         parent>
         <groupId>com.offcngroupId>
         <artifactId>gateway-demoartifactId>
         <version>1.0version>
         <name>gateway-demoname>
         <description>Demo project for Spring Bootdescription>
         <properties>
            <java.version>1.8java.version>
         properties>
            
         <dependencies>
             <dependency>
             	<groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-starter-gatewayartifactId>
             dependency>
    
             <dependency>
                 <groupId>org.springframework.bootgroupId>
                 <artifactId>spring-boot-starter-testartifactId>
                 <scope>testscope>
             dependency>
         dependencies>
         <dependencyManagement>
             <dependencies>
                 <dependency>
                     <groupId>org.springframework.cloudgroupId>
                     <artifactId>spring-cloud-dependenciesartifactId>
                     <version>Hoxton.SR2version>
                     <type>pomtype>
                     <scope>importscope>
                 dependency>
              dependencies>
         dependencyManagement>
        
         <build>
             <plugins>
                 <plugin>
                     <groupId>org.springframework.bootgroupId>
                     <artifactId>spring-boot-maven-pluginartifactId>
                 plugin>
             plugins>
         build> 
    project>
    
  3. 编写启动类(添加@EnableDiscoveryClient

    @EnableDiscoveryClient
    public class CloudGatewayApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(CloudGatewayApplication.class, args);
        }
    
    }
    
  4. 编写路由规则

    server:
      port: 8888
    spring:
      application:
        name: gateway
      cloud:
        nacos:
          discovery:
            server-addr: localhost:8848
        gateway:
          routes: # 下面是配置的例子可以参考
            - id: cms-route
              uri: lb://u-context
              predicates:
                - Path=/api/context/**
              filters:
                - RewritePath=/api/(?>.*),/$\{segment}
    

3.网关中路由有几部分组成?分别代表什么意义?如何配置路由?

路由有四部分组成,分别为:

  • id——路由名
  • uri——接收到请求发送给哪个路径
  • predicates——断言 逻辑判断,比如判断请求路径是否符合某个要求
  • filters——过滤器 可以在发送下游请求之前或之后修改请求和响应。
# 路由配置:spring:  cloud:    gateway:      routes:        - id: nacos-consumer          uri: http://127.0.0.1:18080          predicates:            - Path=/java/hi          filters:            - StripPrefix=1

4. springCloudGateway 包含哪些断言工厂?请简述下请求路径断言的配置方式?

包含的断言工厂有:请求时间、请求Cookie、请求Header、请求Host、请求Method、请求Path、请求查询参数、请求远程地址;

# 请求路径断言的配置方式:spring:cloud: gateway:   routes:      - id: host_route        uri: http://example.org        predicates:        - Path=/foo/{segment},/bar/{segment}

5. SpringCloudGateway包含哪些过滤器工厂?请简述下 如何配置PrefixPath和RewritePath过滤器工厂?

包含的过滤器工厂有:头部过滤器、请求参数过滤器、路径过滤器、请求(响应)体过滤器、状态过滤器、会话过滤器、重定向过滤器、重试过滤器、限流过滤器、熔断器过滤器

# StripPrefix和RewritePath过滤器工厂配置:spring:cloud: gateway:   routes:        - id: nacos-consumer          uri: lb://nacos-consumer          predicates:            - Path=/alibaba/hi          filters:            - StripPrefix=1        - id: nacos-provider          uri: lb://nacos-provider          predicates:            - Path=/java/api/**          filters:            - RewritePath=/java/api/(?.*),/api/$\{segment}

6.在服务集群情况下SpringCloudGateway如何配置路由的uri?简述下使用Java代码配置路由?

在服务集群情况下SpringCloudGateway配置路由的uri

  1. 把网关服务注册到nacos,引入nacos的相关依赖:

    	<dependency>        <groupId>com.alibaba.cloudgroupId>        <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>    dependency>        <dependencyManagement>        <dependencies>            <dependency>                <groupId>org.springframework.cloudgroupId>                <artifactId>spring-cloud-dependenciesartifactId>                <version>Hoxton.SR2version>                <type>pomtype>                <scope>importscope>            dependency>                        <dependency>                <groupId>com.alibaba.cloudgroupId>                <artifactId>spring-cloud-alibaba-dependenciesartifactId>                <version>2.1.0.RELEASEversion>                <type>pomtype>                <scope>importscope>            dependency>        dependencies>    dependencyManagement>
    
  2. 配置nacos服务地址及服务名

    spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: localhost:8848
    
  3. 把网关注入到nacos

    @EnableDiscoveryClient
    
  4. 修改配置,通过服务名路由

    语法:lb://服务名

    lb:LoadBalance,代表负载均衡的方式

    ​ 服务名取决于nacos的服务列表中的服务名

    ​ 如:

    -id: nacos-consumer uri: lb://nacos-consumer
    

    使用Java代码配置路由代码如下:

    @Configurationpublic class RouteLocatorConfig {	@Bean	public RouteLocator customRouteLocator(RouteLocatorBuilder builder){		return builder.routes()                    .route(r -> r.path("/api/hello/**")                                 .filters(f -> f.stripPrefix(1))                                 .uri("lb://nacos-provider"))                    .route(r -> r.path("/ujiuye/hello/**")                                .filters(f -> f.rewritePath("/ujiuye/(?.*)", "/${segment}"))                                .uri("lb://nacos-provider"))                    .build();        }}
    

7.如何配置全局网关?

创建全局过滤器:package com.offcn.filter;import com.fasterxml.jackson.core.JsonProcessingException;import com.fasterxml.jackson.databind.ObjectMapper;import com.google.common.collect.Maps;import org.springframework.cloud.gateway.filter.GatewayFilterChain;import org.springframework.cloud.gateway.filter.GlobalFilter;import org.springframework.core.Ordered;import org.springframework.core.io.buffer.DataBuffer;import org.springframework.http.HttpStatus;import org.springframework.http.server.reactive.ServerHttpResponse;import org.springframework.stereotype.Component;import org.springframework.web.server.ServerWebExchange;import reactor.core.publisher.Mono;import java.util.Map;@Componentpublic class AuthFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {     String token = exchange.getRequest().getQueryParams().getFirst("token");     if (token == null || token.isEmpty()) {         ServerHttpResponse response = exchange.getResponse();         // 封装错误信息         Map responseData = Maps.newHashMap();         responseData.put("code", 401);         responseData.put("message", "非法请求");         responseData.put("cause", "Token is empty");         try {             // 将信息转换为 JSON    如下使用的内置的jackson实现的转换             ObjectMapper objectMapper = new ObjectMapper();             byte[] data = objectMapper.writeValueAsBytes(responseData);             // 输出错误信息到页面             DataBuffer buffer = response.bufferFactory().wrap(data);             response.setStatusCode(HttpStatus.UNAUTHORIZED);             response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");             return response.writeWith(Mono.just(buffer));         } catch (JsonProcessingException e) {             e.printStackTrace();         }     }     return chain.filter(exchange); } @Override public int getOrder() {     return 1;//过滤器的顺序,越小,越先执行 }}

8.简述Sentinel是什么? 谈谈它的发展历史? 以及包括那两部分?

Sentinel是分布式系统的流量防卫兵。随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

发展历史:

​ 2012 年,Sentinel 诞生,主要功能为入口流量控制。

​ 2013-2017 年,Sentinel 在阿里巴巴集团内部迅速发展,成为基础技术模块,覆盖了所有的核心场景。 Sentinel 也因此积累了大量的流量归整场景以及生产实践。

​ 2018 年,Sentinel 开源,并持续演进。

​ 2019 年,Sentinel 朝着多语言扩展的方向不断探索,推出 C++ 原生版本,同时针对 Service Mesh 场景也推 出了 Envoy集群流量控制支持,以解决 Service Mesh 架构下多语言限流的问题。

​ 2020 年,推出 Sentinel Go 版本,继续朝着云原生方向演进。

包括核心库(Java客户端)和控制台(Dashboard)。

9.简述下Sentinel基本概念以及作用?

基本概念:

​ 资源:是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。在接下来的文档中,我们都会用资源来描述代码块。只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。

​ 规则:围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态 实时调整。

作用:

  1. 流量控制
  2. 熔断降级
  3. 系统负载保护

10. 什么是流量控制? sentinel 流量控制有那几个角度? 简述如何进行配置?

流量控制在网络传输中是一个常用的概念,它用于调整网络包发送数据。然而,从系统稳定性角度考虑,在处理请求的速度上,也有非常多的讲究。任意时间到来的请求往往是随机不可控的,而系统的处理能力是有限的。我们需要根据系统的处理能力对流量进行控制。

流量控制有以下几个角度:

  1. 资源的调用关系,例如资源的调用链路,资源和资源之间的关系;
  2. 运行指标,例如 QPS(每秒查询率)、线程数等;
  3. 控制的效果,例如直接限流(快速失败)、冷启动(Warm Up)、匀速排队(排队等待)等。

配置:

QPS流量控制:

​ 直接拒绝:簇点链路–流控

​ 阈值类型为QPS,单机阈值为2,点击新增按钮

​ 冷启动:单机阈值为10,预热时间为5,点击保存

​ 匀速排队:

​ 1、单机阈值为1,选择排队等待,超时时间为20000,点击保存;

​ 2、在postman中,新建一个collection(这里collection名称是sentinel),并把一个请求添加到该collection

​ 1、选择Collections

​ 2、选择sentinel

​ 3、选择Save

​ 4、选择Save As
Request name设置为http://localhost:18080/hi,点击Save to sentinel

​ 3、请求添加成功后,点击run按钮,配置每隔100ms发送一次请求,一共发送20个请求,点击“run sentinel”按钮;
查看控制台,效果如下:可以看到基本每隔1s打印一次
关联限流:
​ 资源名为/hi2,阈值类型为QPS,单机阈值为2,流控模式为关联,关联资源为/hi;
​ 资源名为/hi,阈值类型为QPS,单机阈值为2,流控模式为直接,流控效果为快速失败。
​ 给消费者添加一个controller方法:

@GetMapping("hi2")	public String hi2(){      	return this.providerClient.hello() + "hi2";	}

​ postman配置如下:每个400ms发送一次请求,一共发送50个。每秒钟超过了2次
链路限流:
​ 资源名为/hi2,阈值类型为QPS,单机阈值为2,流控模式为链路,入口资源为/Entrance1,流控效果为快速失败。
线程数限流:
​ 资源名为/hi,阈值类型为线程数,单机阈值为1。
​ 改造controller中的hi方法:

@GetMapping("hi")	public String hi(){		try{          	Thread.sleep(1000);		}catch (InterruptedException e){          	e.printStackTrace();		}      	return this.providerClient.hello();	}

postmain配置:Iterations为50,Delay为10

11. 什么是熔断降级? sentinel进行容量降级包含哪些指标? 简述如何进行配置?

Sentinel熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联错误。当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都自动熔断(默认行为是抛出 DegradeException)。

限流降级指标有三个:

  1. 平均响应时间(RT)
  2. 异常比例
  3. 异常数

配置:

平均响应时间:

资源名为/hi,熔断策略为慢调用比例,最大RT为100,比例阈值为0.1,熔断时长为10,最小请求数为5;

代码中仍然睡了1s

@GetMapping("hi")public String hi(){	try{        Thread.sleep(1000);	}catch (InterruptedException e){        e.printStackTrace();	}    return this.providerClient.hello();}

postmain配置:Iterations为50,Delay为10

异常比例:
当资源的每秒请求量 >= 5,且每秒异常总数占通过量的比值超过阈值(DegradeRule 中的 count)之后,资源 进入降级状态,即在接下的时间窗口(DegradeRule中的 timeWindow,以 s 为单位)之内,对这个方法的调用 都会自动地返回。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。

异常数:当资源近 1 分钟的异常数目超过阈值之后会进行熔断。

12. 如何实现Sentinel规则的持久化?

  1. 引入依赖

        <dependency>        <groupId>com.alibaba.cspgroupId>        <artifactId>sentinel-datasource-nacosartifactId>    dependency>
    
  2. 添加配置:

    spring:  cloud:    sentinel:      transport:        dashboard: 192.168.188.138:8080        port: 8719      datasource:        consumer:          nacos:            server-addr: 192.168.188.138:8848            dataId: ${spring.application.name}-sentinel-rules            groupId: SENTINEL_GROUP            data-type: json            rule_type: flow
    
  3. nacos中创建流控规则
    Data ID中写dataId
    Group中写groupId
    配置格式选JSON
    配置内容:

    [  {    "resource": "/hi",    "limitApp": "default",    "grade": 1,    "count": 2,    "strategy": 0,    "controlBehavior": 0,    "clusterMode": false  }]
    

13. Sleuth是什么? 如何使用Sleuth实现服务请求的分布式链路追踪?简述其配置?

Spring Cloud SleuthspringCloud实现了一个分布式链路追踪解决方案,大量借鉴了DapperZipkinHTrace等链路追踪技术。对于大多数用户而言,Sleuth应该是不可见的,并且您与外部系统的所有交互都应自动进行检测。您可以简单地在日志中捕获数据,也可以将其发送到远程收集器服务。

使用Sleuth实现服务请求的分布式链路追踪步骤和配置:

  1. 引入sleuth的依赖

    <dependency>  <groupId>org.springframework.cloudgroupId>  <artifactId>spring-cloud-starter-zipkinartifactId>dependency>
    

    zipkin的启动器包含了sleuth的依赖。

  2. 配置zipkin的相关信息

    spring:  zipkin:    base-url: http://192.168.188.138:9411    discovery-client-enabled: false    sender:      type: web
    
  3. 重启consumer/provider服务后,访问消费者:http://localhost:18080/hi。

Day03

1.简单介绍下优学题库? 用到了那些技术栈(前端 、后台)?

优学题库是一个以微服务为架构的在线考试题库项目,前后端分离,其中包括实体分类管理、考试题目管理、在线答题等众多功能模块,是一套完整的互联网应用系统。

后端:SpringBoot+SpringCloud GateWay+MybatisPlus+Nacos

前端:Vue+ElementUI+Node.js

2.简述下优学题库的项目结构?

该项目使用前后端分离技术,前端由admin-vue,小程序客户端两部分组成,所有的请求都必须先通过网关GateWay,然后网关将请求分发给后端的其他微服务模块,有u-context,u-member,u-question,renrenfast这些微服务,Nacos作为这些微服务的注册中心,Sentinel用于限流,Seata用于分布式事务控制,SchedulerX用于分布式任务调度,其中还有一些功能采用第三方服务,比如短信,支付等功能。项目中还使用了一些其他框架,比如Redis(缓存),ElasticSearch(搜索)等等

3.优学题库中用到了哪些数据库? 这个数据库分别对象哪些模块?

uxue_admin:管理后台数据库 ————renrenfast-fast

uxue_cms:广告内容服务数据库 ————u-context

uxue_qms:题目服务数据库 ————u-question

uxue_ums:会员服务数据库 ————u-member

4.如何在git创建一个代码仓库? 如何下载到本地?本地修改后如何同步到git代码仓库?

登录gitee账号,点击右上角"+"号选择新建仓库,仓库名称为uxue,状态为私有,语言为java,选择"使用Readme文件初始化这个仓库",点击创建。

点击进入到giteeuxue项目,复制克隆里HTTPS的网址,然后在本地创建一个空文件夹为uxue,打开这个文件夹路径的命令窗口,输入命令git clone 复制的内容 ,执行后就好了。

uxue文件夹中,添加或创建一个pom.xml文件(将其变为Maven工程),然后使用IDEA打开,打开IDEA下方的Terminal窗口,输入命令git add .(添加)git commit -m "备注"(提交到本地仓库),git push origin master(推送到远程仓库)。

5.简述下你是如何搭建项目的管理后台的?

微服务:创建SpringBoot项目,导入依赖,修改yml配置文件,在启动类上添加注解@EnableDiscoveryClient(开启服务发现),在uxuepom.xml文件中对模块进行聚合(u-context)。

后台后端:使用renren-fast

https://gitee.com/renrenio/renren-fast.git

后台前端:使用renren-fast-vue

https://gitee.com/renrenio/renren-fast-vue.git

6.简述如何使用人人开源的代码生成器,生成代码?

  1. 下载人人开源的代码生成器框架

    git clone https://gitee.com/renrenio/renren-generator.git
    
  2. 导入生成器代码到uxue项目

  3. 修改application.yml,把数据库及其连接信息改成广告的数据库:uxue_cms

  4. 修改generator.properties

  5. 修改controller模板文件src/main/resources/template/Controller.java.vm暂时删除引入的包,后面再引入

    //import org.apache.shiro.authz.annotation.RequiresPermissions;
    

    注释掉方法中RequiresPermissions注解,后面再引入

    //@RequiresPermissions("${moduleName}:${pathName}:list")
    
  6. 启动逆向工程RenrenApplication

  7. 启动成功,监听端口号为80。浏览器访问,点击renren-fast,出现生成界面,可以看到数据表

  8. 选中全部表,点击生成代码按钮,即可生成一个压缩包,被下载下来。

7.如何对 广告、用户、问题等模块进行配置,遇到公共的依赖等如何处理?

  1. 创建一个Maven模块(u-common),将公共的依赖添加导pom.xml文件中
  2. u-common中创建utils包和xss
  3. utils包存放一些从renren-fast模块中复制过来的文件:Constans.javaPageUtils.javaQuery.javaR.javaRRException.java
  4. xss包存放一些从renren-fast模块中复制过来的文件:HTMLFilter.javaSQLFilter.java
  5. u-common进行clear(清理)和install(安装到本地仓库)
  6. 当其他微服务需要公共的依赖时,只需导入u-common这个依赖即可

8.如何发布各微服务到nacos上,需要进行哪些配置?

  1. 添加依赖spring-cloud-starter-alibaba-nacos-discovery

  2. 修改yml文件

    spring:  cloud:    nacos:      discovery:        server-addr: localhost:8848
    
  3. 启动类添加注解@EnableDiscoveryClient

9.如何搭建网关,如何配置相关模块的路由,如何发布网关微服务到nacos上?

(1)创建一个SpringBoot工程,名为cloud-gateway

(2)添加依赖spring-cloud-starter-gateway

(3)修改yml文件,配置网关路由规则

spring.cloud.gateway.routes:  -  id: cms-route     uri: lb://u-context     predicates:        -  Path=/context/**     filters:       -  RewritePath=/(?>.*),/$\{segment}

Day04

1.如何启动人人开源管理前端,要从开发工具、环境配置、相关命令方面去介绍?

  1. 安装nodejs 10.14.2
  2. 安装vscode 1.34.0版本
  3. 保存工作区
  4. 进入VSCODE终端
  5. npm -v查看npm版本
  6. 配置配置淘宝镜像cnpm npm install -g cnpm --registry=https://registry.npm.taobao.org
  7. npm install [email protected] -g #安装指定版本的npm
  8. 安装node_modules依赖包 cnpm install
  9. 编译打包运行前端项目 npm run dev

2.如何配置前端使用api网关请求后端api接口?

  1. 修改配置文件对接后端api地址 文件:renren-fast-vue\static\config\index.js

  2. window.SITE_CONFIG['baseUrl'] = 'http://localhost:8080/renren-fast';
    替换为
    window.SITE_CONFIG['baseUrl'] = 'http://localhost:8888/api'; // 网关地址

  3. 配置cloud-gateway转发到renren-fast的路由

      routes:                - id: renrenfast-route # 人人后台服务路由          uri: lb://renren-fast          predicates:            - Path=/api/**          filters:            - RewritePath=/api/(?.*),/renren-fast/$\{segment}
    

3.什么是跨域? 如何我们项目中如何解决跨域的?

  1. 什么是跨域
    跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器不同的域、协议或端口请求一个资源时,资源会发起一个跨域 HTTP 请求。

  2. 如何解决跨域:
    添加响应头,配置当次请求允许跨域
    cloud-gateway模块添加解决跨域的配置文件GatewayCorsConfiguration.java

    @Configurationpublic class GatewayCorsConfiguration {    @Bean    public CorsWebFilter corsWebFilter() {        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();        CorsConfiguration corsConfiguration = new CorsConfiguration();        // 配置跨域        corsConfiguration.addAllowedHeader("*"); // 允许所有请求头跨域        corsConfiguration.addAllowedMethod("*"); // 允许所有请求方法跨域        corsConfiguration.addAllowedOrigin("*"); // 允许所有请求来源跨域        corsConfiguration.setAllowCredentials(true); //允许携带cookie跨域,否则跨域请求会丢失cookie信息        source.registerCorsConfiguration("/**", corsConfiguration);        return new CorsWebFilter(source);    }}
    

    注释renren-fast跨域配置 重启各个服务及网关,测试即可成功登录

4.如何开发配置题目分类服务目录和菜单?如何显示新增、批量删除按钮的?

  1. 添加题目分类服务目录:选择管理界面–系统管理–菜单管理,点击 新增按钮

    添加题目菜单:选择管理界面–系统管理–菜单管理,点击 新增按钮

    拷贝\main\resources\src\views\modules\question目录到前端目录 renren-fast-vue\src\views\modules

    修改colud-gateway网关配置,配置转发题目微服务

    qms-route的路由配置一定要配置在renrenfast-route之前,拥有加载顺序

  2. 显示新增、批量删除按钮:

    打开前端工程renren-fast-vue找到配置文件src\utils\index.js

    暂时不判断权限,全部返回true

5.什么是逻辑删除? 如果需要查看程序调用数据是发送的sql语句等情况应该如何配置?

逻辑删除:就是不直接把数据记录从数据库删除,而是采用设置删除标记来标识数据记录被删除

查看sql语句配置:

logging:level: com.offcn.question: debug

6.如何实现模糊查询功能?如何实现分页功能?

实现模糊查询功能:
修改实现类TypeServiceImpl的方法queryPage

@Overridepublic PageUtils queryPage(Map<String, Object> params) { //1、获取查询关键字 String key= (String) params.get("key"); //2、创建查询条件对象 QueryWrapper queryWrapper = new QueryWrapper<>(); //3、设置查询条件 if(!StringUtils.isEmpty(key)){     queryWrapper.eq("id",key).or().like("type",key); } IPage page = this.page(         new Query().getPage(params),         queryWrapper ); return new PageUtils(page);}

配置分页

@Configuration@EnableTransactionManagementpublic class MyBatisConfig { //引入分页插件 @Bean public PaginationInterceptor paginationInterceptor() {     PaginationInterceptor paginationInterceptor = new PaginationInterceptor();     // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false     paginationInterceptor.setOverflow(true);     // 设置最大单页限制数量,默认 500 条,-1 不受限制     paginationInterceptor.setLimit(1000);     return paginationInterceptor; }}

7.如何实现题目类型下拉菜单数据的查询?

  1. 获取根据分类获取题库列表数据接口

    接口:TypeService 增加获取全部分类方法

    实现类:TypeServiceImpl实现

  2. 编写获取题库分类控制器

    修改TypeController,增加获取全部分类接口

  3. 前端代码编写

    修改question-add-or-update.vue

    修改数据结构,定义题目类型下拉菜单数据

    修改方法,当用户点击打开新增、或者修改页面的时候,调用后台接口获取全部题目类型数据

  4. 点击新增、或者修改,可以看到题目类型下拉菜单成功显示

8.新增题目 如何处理是否显示、是否删除?

  1. 修改页面question-add-or-update.vue

     不显示 显示
    
  2. 修改数据结构,定义是否显示、删除标记的初始化值
    enable: '1'
    delFlag: '0'

    dataForm: {    id: 0,    title: '',    answer: '',    level: '',    displayOrder: '',    subTitle: '',    type: '',    enable: '1',    delFlag: '0',    createTime: '',    updateTime: ''},
    
  3. 当选中数据进行修改的时候,是否显示和删除没有回显。进行如下操作使其回显
    关键点: data.question.enable + ''
    data.question.delFlag + ''

    if (data && data.code === 0) {    this.dataForm.title = data.question.title    this.dataForm.answer = data.question.answer    this.dataForm.level = data.question.level    this.dataForm.displayOrder = data.question.displayOrder    this.dataForm.subTitle = data.question.subTitle    this.dataForm.type = data.question.type    this.dataForm.enable = data.question.enable + ''    this.dataForm.delFlag = data.question.delFlag + ''    this.dataForm.createTime = data.question.createTime    this.dataForm.updateTime = data.question.updateTime}
    

9.如何快速设置是否显示?

修改页面question.vue添加更新状态方法

methods: {     // 更新题目是否显示   updateQuestionStatus (data) {     console.log(data)       // 析构函数提取data中的id和enable数据     let {id, enable} = data     this.$http({       url: this.$http.adornUrl('/question/question/update'),       method: 'post',       data: this.$http.adornData({id, enable}, false)     }).then(({ data }) => {       this.$message({         type: 'success',         message: '状态更新成功'       })     })   }},

修改页面question.vue

 

10.简述下如何实现题目的导入、导出功能?

  1. 后端:

    1. 修改项目u-question的接口QuestionService增加导入、导出接口定义

      //导入 public Map importExcel(MultipartFile file);//导出 public Workbook exportExcel();
      
    2. 修改实现类QuestionServiceImpl实现导入、导出方法

    3. 修改控制器QuestionController实现导入、导出方法

      @PostMapping("/upload")
      
  2. 前端:

    1. renren-fast-vue前端工程/src/views/modules/question/目录下新增视图文件question-import.vue

    2. 修改题目维护页面question.vue import ImportExcel from './question-import'
      声明允许显示导入弹窗变量 importVisible: false
      把导入页面注册到当前页面组件: ImportExcel
      添加导入导出点击触发方法:
      在页面模板区域,添加 导入、导出按钮:

      									导入
      

      在模板中注册导入窗口:

       
      

11.如何实现题库分类数量统计分析?

  1. 后端:

    1. 打开java模块u-question ,编辑接口QuestionService新增统计分类题目数量方法

      public List<Map<String, Object>> countTypeQuestion();
      
    2. 编辑接口实现类QuestionServiceImpl,编写统计分类题目数量实现方法

      public List<Map<String, Object>> countTypeQuestion() {        //SELECT COUNT(*) AS num,TYPE FROM qms_question WHERE 1=1 GROUP BY TYPE        QueryWrapper queryWrapper = new QueryWrapper().select("TYPE,COUNT(TYPE) AS num").groupBy("type");        List> mapList = questionDao.selectMaps(queryWrapper);    return mapList;}
      
    3. 编辑QuestionController,新增统计分类题目数量方法

      @RequestMapping("/countTypeQuestion")
      
  2. 前端:
    1.前端项目renren-fast-vue/src/views/modules/question目录 新增统计注册用户数量页面 echarts.vue
    2.配置用户注册统计菜单:菜单管理——题目管理——querstion/echarts

Day05

1.简述什么OSS云存储? 如何开发阿里云存储?如何测试文件上传?

  1. 什么是oss云存储:
    阿里云对象存储OSS(Object Storage Service)是阿里云提供的海量、安全、低成本、高持久的云存储服务。我们需要将上传的文件进行存储,传统的文件上传到本机已经不适用于分布式系统,自己搭建服务器有复杂性和维护成本,所以我们可以使用市面上成熟的文件存储服务,如阿里云OSS对象存储。

  2. 如何开发:

    2.1 登陆

    2.2 创建Bucket并新建文件夹

    2.3 申请accesskey

    1. 创建用户
    2. 添加权限AliyunOSSFullAccess
    3. 点击用户列表,点击有用户,创建AccessKey获得AccessKey IDAccessKey Secret
  3. 文件文件上传测试:

    3.1 在模块中引入SDK依赖

    3.2 测试类中编写文件上传测试方法

    1. 创建三个字符串变量,endpointaccessKeyIdaccessKeySecret
    2. 创建ossClient实例调用build方法,传入三个字符串
    3. 创建要上传文件的输入流
    4. 调用ossClient实例的putObject方法,传入参数
    5. 关闭ossClient
    6. 测试完成

2.分别简述通过应用服务器中转上传和直接javascript客户端上传到oss上传原因?

  1. 通过应用服务器中转上传

    用户数据需先上传到应用服务器,之后再上传到OSS

  2. 直接javaScript客户端上传到oss

    1. 用户发送上传Policy(策略)请求到应用服务器。
    2. 应用服务器返回上传Policy和签名给用户。
    3. 用户直接上传数据到OSS

3.如何解决直接javascript客户端上传到oss的时候的安全隐患?

采用JavaScript客户端直接签名时,AccessKeyIDAcessKeySecret会暴露在前端页面,因此存在严重的安全隐患。因此,OSS提供了服务端签名后直传的方案来解决安全隐患。

4.如何实现图片上传到oss云存储?如何在题目分类新增页面增加上传控件实现图片上传?

  1. 图片上传oss云存储:

    1. 创建三个字符串变量,endpointaccessKeyIdaccessKeySecret
    2. 创建ossClient实例调用build方法,传入三个字符串
    3. 创建要上传图片的输入流
    4. 调用ossClient实例的putObject方法,传入参数
    5. 关闭ossClient
    6. 上传完成
  2. 页面增加上传控件实现图片上传:

    1. 在前端工程renren-fast-vue目录src/views/modules/common目录下 创建上传页面 singleUpload.vue

    2. 在前端工程renren-fast-vue目录src/views/modules/question目录下 修改页面 type-add-or-update.vue引入上传控件

      1. export default上面引入:

        import SingleUpload from "../common/singleUpload" // 引入单文件上传组件
        
      2. 注册上传组件:

        export default {	components:{ SingleUpload }}
        
    3. 修改分类logo输入框,改成上传按钮

5.简述下如何实现广告内容的前端维护管理?

  1. 将人人代码生成器生成的前端页面导入,拷贝\main\resources\src\views\modules\context目录到前端目录renren-fast-vue\src\views\modules
  2. 添加广告内容管理目录(一级菜单)
  3. 添加广告轮播图管理菜单(二级菜单)
  4. 添加广告资讯管理菜单(二级菜单)
  5. 配置网关转发,找到cloud-gateway,修改配置文件application.yml
  6. 修改广告轮播图广告配图上传
  7. 修改广告资讯广告配图上传

6.简述下如何实现用户管理前端维护管理?

  1. 拷贝前端代码到 前端工程renren-fast-vue

    拷贝\main\resources\src\views\modules\member目录到前端目录 renren-fast-vue\src\views\modules

  2. 添加用户管理目录(一级菜单)

  3. 添加用户列表管理菜单(二级菜单)

  4. 添加用户充值记录管理菜单(二级菜单)

  5. 配置网关转发,找到cloud-gateway,修改配置文件application.yml

7.如何开发微信小程序登录及验证调用接口?请简述用户登录认证的流程?

  1. 开发微信小程序登录及验证调用接口

    1. common模块中引入JWT依赖库并导入JWT工具类JWTUtil

    2. 引入redis依赖

    3. 在用户模块controller中编写loginrefreshtoken方法

    4. 配置网关路由转发

    5. 配置网关过滤器,拦截微信客户端请求验证token

    6. 修改pom.xml引入common依赖,排除不需要的mybatis-plus-boot-starter依赖

    7. 编写网关过滤器类

    8. 配置网关过滤器

      @Configurationpublic class GatewayCorsConfiguration {    @Bean    public JwtCheckGatewayFilterFactory jwtCheckGatewayFilterFactory(){        return new JwtCheckGatewayFilterFactory();    }}
      
    9. 修改网关配置,加入过滤器

      filters:  - RewritePath=/(?>.*),/$\{segment}
      
  2. 用户登陆认证流程

    1. 微信小程序使用账号密码登陆
    2. 用户管理后台使用账号和密码查询认证,验证成功,生成令牌,存入redis,并返回前端
    3. 账号执行其操作时会先经过网关,路由过滤器验证令牌是否合法,合法继续操作,不合法返回错误信息。

8.如何开发微信小程序分类、及题库、广告轮播图读取调用接口?

  1. 获取题库分类接口
    修改网关配置文件,增加weixin-question-route路由

    - id: weixin-question-route # 提供微信客户端调用的,题库微服务路由    uri: lb://u-question    predicates:      - Path=/question/**    filters:      - RewritePath=/(?.*),/$\{segment}      - JwtCheck
    
  2. 获取广告轮播图数据接口
    修改网关配置文件,增加weixin-context-route路由

    - id: weixin-context-route # 提供微信客户端调用的,用户微服务路由  uri: lb://u-context  predicates:    - Path=/context/**  filters:    - RewritePath=/(?.*),/$\{segment}    - JwtCheck
    

9.简述如何编写接口文档?

接口文档应该包含以下信息:

  1. 基本信息
    1. Path:请求路径
    2. Method:请求方式
    3. 接口描述:接口的详细描述
  2. Request
    1. Headers:请求头
    2. Query:参数
    3. Body:请求体
  3. Response

Day06

1.什么是微信小程序? 微信小程序和移动应用相比有哪些区别?以及如何选择?

小程序是一种不需要下载安装即可以使用的应用,他实现了应用“触手可及”的梦想,用户扫一扫或者搜一下即可打开应用。也体现了“用完即走”的理念,用户不用担心是否安装太多应用的问题。应用将无处不在随时可用,但又无需安装卸载。

小程序和移动应用的区别

  1. 下载:App 从应用商店(如 App Store)里下载;小程序 通过微信(扫描二维码、搜索)直接获得;
  2. 安装:App 安装在手机内存中,就像自己买了辆车放在车库里随时开;小程序不需要安装,就像免费用嘀嘀打车,召之即来用完拜拜;
  3. 占用空间:App 会一直存在手机中占用空间,太多的 App 可能会导致内存不足;小程序因为不需要安装,占用内存空间忽略不计;
  4. 广告推送:App 会隔三差五给用户推送广告,太多未读提示会逼死强迫症;小程序不允许主动给用户发送广告,仅能回复模版消息;
  5. 机会:App市场已经饱和,几乎所有的领域都已经被覆盖;小程序是一片蓝海,在新的使用场景下有很多瓜分蛋糕的好机会;
  6. 开发:App 需要适配市场上很多款的主流手机,开发成本大;小程序 一次开发就可以自动适配所有手机;
  7. 发布:App 需要向十几个应用商店提交审核,且每个应用商店要求的资料都不一样,非常繁琐;小程序 只需要提交到微信公众平台审核 ;
  8. 用户群:App 面向所有智能手机用户,截止2015年约19亿台;小程序面向所有微信用户,约8亿人 ;
  9. 开发周期:一款完善的双平台 App 平均的开发周期约3个月;小程序 平均开发周期约2周,仅为App的六分之一;
  10. 功能:App 可以实现完整功能;小程序仅限微信提供的接口功能;

如何选择:

  • 使用频率高而且还很重要不适合用微信小程序,应该用原生的app开发
  • 使用频率低而且很重要应该用微信小程序开发
  • 使用频率高但是不重要应该用小程序为入口导向原生app
  • 使用频率不高也不重要优选小程序开发

2.微信小程序用到的技术点有哪些?常用的api包括哪些内容?

技术点:

  • 并不是HTML5/CSS3技术实现
  • 抛弃了臃肿的WebView
  • 采用了JavaScriptCore动态解析
  • 大量借鉴React.js + ReactNative.js思想

常用api

  • 视图容器:视图(View)、滚动视图、Swiper
  • 基础内容:图标、文本、进度条
  • 表单组件:按钮、表单等等
  • 操作反馈导航
  • 媒体组建:音频、图片、视频。
  • 地图画布文件操作能力
  • 网络:上传下载能力、WebSocket
  • 数据:数据缓存能力
  • 位置:获取位置、查看位置
  • 设备:网络状态、系统信息、重力感应、罗盘
  • 界面:设置导航条、导航、动画、绘图等等
  • 开放接口:登录,包括签名加密,用户信息、微信支付、模板消息

3.如何开始开发一个微信小程序? 需要那些准备步骤?简单介绍下微信小程序的目录结构?

  1. 注册微信小程序账号
  2. 下载微信小程序开发工具,下载完成以后直接安装即可使用,使用时需要用微信扫描二维码
  3. 打开工具后选择小程序开发,然后点击添加项目,点击 + 号,新建小程序,点击新建按钮,即可新建一个小程序项目

​ 小程序包含一个描述整体程序的 app 和多个描述各自页面的 page。一个小程序主体部分主要由app.jsapp.jsonapp.wxss(不是必须的)组成,必须放在项目的根目录下。

4.一个微信小程序页面部分包含那四个文件?如何快速生成某个页面的文件?

一个小程序页面由四个文件组成,分别是jswxmljsonwxss,其中jswxml是必需的,jsonwxss不是必需。js用于页面逻辑,wxml用于页面结构,json用于页面配置,wxss用于页面样式。

新建页面时,在pages项中添加新建页面配置项,将会自动创建页面。小程序页面文件夹名与文件名相同。

5.app.json 文件有什么功能? 可以进行哪些配置? app.json中window配置和某个页面中的xxx.json配置有什么区别?

app.json文件用来对微信小程序进行全局配置,决定页面文件的路径、窗口表现、设置网络超时时间、设置多 tab 等

app.json可以进行如下配置:

  • pages:设置页面路径
  • window:设置默认页面的窗口表现
  • tabBar:设置底部tab的表现
  • netWorkTimeout:设置网络超时时间
  • debug:设置是否开启debug模式

除了全局的app.json配置外,还可以用.json文件对小程序项目中的每一个页面进行配置,但只能设置本页面的window配置项的内容,页面.json文件中的window配置值将覆盖app.json中的配置值。

6.什么是tabBar?请简述下常见的属性以及意义?

小程序可以是多标签页切换的应用,需要通过tarBar配置项来指定标签页的表现,及标签页切换时所显示的对应页面。

常见属性:

  • color:tab上的文字默认颜色
  • selectedColor:tab上的文字选中时的颜色
  • backgroundColor:tab的背景色
  • borderStyle:tabber上边框的颜色,仅支持black/white
  • list:tab的列表,最少2个最多5个tab
  • position:可选值bottomtop

其中list接收一个数组,数组中的每个项都是一个对象,属性如下:

  • pagePath:页面路径,必须在pages中先定义
  • text:tab上按钮文字
  • iconPath:图片路径,icon大小限制40kb,建议尺寸81px*81px,当position为top时,此参数无效,不支持网络图片
  • selectedIconPath:选中时的图片路径,icon大小限制40kb,建议尺寸81px*81px,当position为top时,此参数无效

7.什么是tabBar?请简述下常见的属性以及意义?

数据是通过{{}}来绑定的,在index.js中定义数据

通过对button设置点击事件,动态的更改绑定数据的内容

  1. button设置点击事件
  2. index.js中实现点击事件btnClick:function(){this.setData({text:"修改后的内容"})}

8.如何使用条件标签和循环标签? 如何使用模板?

条件标签:

  1. 定义if标签index.wxml{{textif}}
    index.js

     Page({            data:{            text:"这里是内容",            textif:"if判断",            show:true        },
    

    show的值为true 显示,为fasle不显示;修改index.js增加根据button的点击事件控制show的结果,动态切换数据,这样可以通过点击button来控制显示或者不显示textif的数据

循环标签:

  1. 创建数组数据

    index.js

      data:{            text:"这里是内容",            textif:"if判断",            show:false,            news: ['aaa','bbb','ccc','ddd']          }
    
  2. 循环遍历显示数据

    index.wxml这是循环的内容

    如果需要显示for中的内容,通过:wx:for-item 获取遍历的各个节点元素,通过index获取索引,也可以根据点击事件动态改变new的数据

模板的使用:

  1. 通过include引入

    1. pages下新建template文件,然后在template中创建header.wxml这是头布局

    2. 然后在index.wxml中引入

  2. 通过import引入

    1. template下创建footer.wxml文件

    2. index.wxml中引入