Resumen del proyecto de gestión de recursos humanos

Resumen del proyecto de gestión de recursos humanos

1. Git

1. Introducción a git

Git es similar a SVN y es una herramienta de control de versiones utilizada para el desarrollo colaborativo de proyectos. La diferencia es que SVN es una
herramienta de control de versiones centralizada y Git es una herramienta de control de versiones distribuida.

2. Uso de git

①Agregue el código recién escrito

②Ejecute git commit, commit code y envíe a local

③ Push 【git push】

④Pull 【git pull】

3. operación de la interfaz gráfica de git

TortoiseGIT

Idea usa Git

4. Manejo de conflictos

Tipo y SVN, SVN después de un conflicto tiene varias versiones de archivos, pero git no produce múltiples versiones de archivos, sólo tenemos que cambiar la cultura del conflicto
tras pieza, con la etiqueta "resolver" y luego enviar el código es correcto, y otra SVN Resolver conflictos es exactamente lo mismo.

5. repositorio remoto de Git

GitLab

Segundo, construir la estructura del proyecto de fondo

1. Centro de registro Eureka

1.1 Dependencia

<!--eureka服务端的场景启动器-->
<dependencies> 
     <dependency> 
         <groupId>org.springframework.cloud</groupId> 
         <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> 

1.2. Configuración

server: 
	port: 8761 
eureka: 
	instance: 
		hostname: localhost 
	client: 
		registerWithEureka: false 
		fetchRegistry: false 
		serviceUrl: 
			defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #单机版

1.3. Clase de inicio

@SpringBootApplication 
@EnableEurekaServer 
public class EurekaServerApplication { 
    public static void main(String[] args) { 							             			SpringApplication.run(EurekaServerApplication.class,args);
   } 
}

2. Servidor del centro de configuración

2.1. Crear un proyecto Springboot, solo mantener recursos y almacenar archivos de configuración

2.2 Dependencia

<!--配置中心服务端场景启动器-->
<dependencies>  
    <dependency> 
        <groupId>org.springframework.cloud</groupId> 
        <artifactId>spring-cloud-config-server</artifactId> 
    </dependency> 
    <!--eureka-client的场景启动器--> 
    <dependency>
        <groupId>org.springframework.cloud</groupId> 
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
</dependencies>

2.3. Configuración

server:
  port: 6969

#springcloud从本地读取配置文件
#spring:
#  cloud:
#    config:
#      server:
#        native:
#          search-locations: D:/itsource/workspace/hrm-config/src/main/resources
#  profiles:
#    active: native
spring:
  application:
      name: CONFIG-SERVER
  #从gitee中拉取配置文件
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/solargen_admin/hrm-config.git #git仓库的路径
          searchPaths: src/main/resources #从仓库路径中哪个目录中加载

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  instance:
    instance-id: config-server:6969 #服务实例的标识
    prefer-ip-address: true #以ip注册

2.4 Clase de inicio

@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {

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

}

3. Gateway

3.1 Dependencia

<dependencies>
    <!--网关的场景启动器-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
    </dependency>
    <!--eureka-client的场景启动器-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <!--配置中心客户端-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
</dependencies>

2.2 Configuración

#配置中心客户端配置
spring:
  cloud:
    config:
      discovery:
        enabled: true
        service-id: CONFIG-SERVER
      name: application-zuul
      profile: dev

#eureka客户端配置
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

En el repositorio de archivos de configuración: application-zuul-dev.yml

server:
  port: 1299
spring:
  application:
    name: ZUUL-SERVICE
eureka:
  instance:
    instance-id: zuul-service:1299 #服务实例的标识
    prefer-ip-address: true #以ip注册
zuul:
  ignored-services: "*"
  prefix: /servies
#路由配置
  routes:
    user:
      path: /myusers/**
      serviceId: users

2.3. Clase de inicio

@SpringBootApplication
@EnableZuulProxy
public class ZuulApplication {

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

}

3. Mybatis-Plus

mybatis-plus es una herramienta que utiliza mybatis, perfectamente integrada en los proyectos de mybatis, solo mejoras, sin cambios, suave como la seda.

1. El núcleo de mybatis-plus

(1) interfaz CRUD

(2) constructor condicional

(3) Complemento de paginación

(4) Generador de código

4. Los inquilinos se instalan

1. Proceso de entrada del inquilino

El front-end muestra una página de entrada del inquilino, completa la información básica del inquilino y el paquete comprado, pasa los parámetros al back-end, inserta la información del inquilino en la tabla del inquilino y luego inserta el nombre de usuario y la contraseña en la información del inquilino y la clave principal del inquilino que acaba de devolver Tabla de empleados, luego inserte la clave principal de la tabla de empleados devuelta en la tabla de inquilinos, y finalmente inserte la clave primaria de inquilinos y la identificación del paquete en la información del inquilino en la tabla intermedia de paquetes de inquilinos. Este negocio debe agregarse a la gestión de transacciones para garantizar la coherencia de las transacciones.

2. Carga del logotipo del inquilino (sistema de archivos distribuido fastdfs)

2.1 El principio arquitectónico de fastdfs [rastreador de almacenamiento]

  • rastreador y almacenador conectados por latidos
  • El rastreador es responsable de recibir las solicitudes de los usuarios y de asignar el almacenamiento a los usuarios en equilibrio de carga
  • el almacenador recibe los datos y los almacena, y devuelve el ID de archivo de usuario o encuentra el archivo de acuerdo con el ID de archivo

2.2. Use fastdfs para realizar el proceso de carga de archivos

  • El racker y el almacenador mantienen un enlace de latidos, el usuario solicita el rastreador y la carga del rastreador equilibra el rastreador con el usuario. El usuario carga el archivo en el rastreador. El rastreador persiste el archivo y devuelve un ID de archivo (nombre de grupo de almacenamiento + nombre de archivo) al usuario. El usuario almacena el ID de archivo A la base de datos.
  • Cuando el usuario necesita descargar el archivo, también solicita el rastreador. El equilibrador de carga del rastreador asigna el almacenamiento al usuario. El usuario encuentra el archivo en el almacenador a través del ID de archivo y lo descarga.

5. Curso de gestión de tipos + redis caché central

1. Árbol de tipos, la forma de obtener tipos de cursos de nivel inalámbrico

  • El primero es usar la recursividad, comenzando desde el tipo primario, y luego de manera recursiva, hasta la ubicación sin el tipo primario. Este método tiene poca legibilidad de código y puede causar un desbordamiento de la pila, que básicamente no se usa.
  • El segundo tipo es bucles anidados, primero encuentre todos los tipos, recicle y recorra, y luego agregue el tipo padre a la Lista, y luego anide todos los tipos de bucle para encontrar el tipo padre, que es el tipo del bucle de primer nivel La identificación principal corresponde a la identificación del tipo del bucle de la segunda capa. Lo mismo es el tipo primario-secundario, y luego se puede agregar el subtipo correspondiente al tipo primario. Cuando hay más datos de este tipo, hay más árboles para consultar y la eficiencia no es alta. Usa menos
  • El tercero es loop + map, encuentre todos los tipos y agréguelos al mapa (id es la clave, type object es value), luego recorra todos los tipos y agregue el tipo padre a List, y luego agregue otros tipos de padres id se usa como la clave del mapa para encontrar todos los tipos principales de este tipo. Si hay un tipo principal, agréguelo al tipo principal. Este método es más eficiente y mucho más utilizado

2. redis optimizado tipo de curso

  • ¿Por qué el tipo de curso se almacena en caché en redis?

    • Debido a que el tipo de curso es un tipo con muchas consultas y pocos cambios de datos, estos datos son muy adecuados para el almacenamiento en caché, lo que puede reducir la presión de la base de datos y resolver problemas de alta concurrencia.
  • ¿Qué tipo de datos es el tipo de curso almacenado en caché en reids? Por qué

    • Caché en Redis con cadena JSON, ya que los datos del tipo de curso son relativamente pequeños, de esta manera es muy conveniente y eficiente

3. Proceso de caché de Redis

① Después de recibir la solicitud del tipo de curso de solicitud de front-end, consulta directamente redis;

② Determinar si los datos en el caché existen;

③Si existe, devuelva los datos directamente;

④Si no existe, consulte los datos de la base de datos, sincronice los datos detectados con redis y luego vuelva al front end.

4. Problemas encontrados por redis

4.1 Penetración de caché

(1) Caso:

Caché la información del usuario en redis, utilizando la identificación del usuario como clave Base de datos. Si la concurrencia es alta, este fenómeno penetra directamente en el caché de redis y una gran cantidad de solicitudes accede directamente a la base de datos, lo que abrumará la base de datos y hará que la base de datos se bloquee.

(2) Solución:
  • Filtro de floración
  • Si el caché no existe, acceda a la base de datos, si la base de datos no consulta los datos, almacene un valor nulo en redis y establezca un tiempo de caducidad, [clave (-1): valor (nulo)], devuelva directamente.

4.2 Desglose de caché

(1) Caso:

Al mismo tiempo, una gran cantidad de solicitudes para acceder a una determinada clave, y esta clave acaba de expirar o redis aún no se ha iniciado en la memoria caché, lo que resulta en una gran cantidad de solicitudes para acceder a la base de datos

(2) Solución:

Bloqueo de código de sincronización + doble verificación

@Override
public List<CourseType> loadDataTree() {

    //1、从缓存中获取数据
    AjaxResult result = redisClient.getStr(KEY);
    if(!result.isSuccess()){
        return null;
    }
    //2、判断缓存中的数据是否存在
    String courseTypes = (String) result.getResultObj();
    if(StringUtils.isEmpty(courseTypes)){
        //缓存不存在
        synchronized (this){
            result = redisClient.getStr(KEY);
            if(!result.isSuccess()){
                return null;
            }
            courseTypes = (String) result.getResultObj();
            if(StringUtils.isEmpty(courseTypes)){
                logger.debug("缓存中没有数据,查询数据库并缓存......");
                List<CourseType> courseTypeList = null;
                //4、如果不存在,则查询数据库,将查询结果缓存到redis中
                courseTypeList = loopMapCourseTypes();
                try {
                    //模拟这边业务要执行2000ms
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                String jsonString = JSONArray.toJSONString(courseTypeList);
                redisClient.setStr(KEY,jsonString);
                //5、再将结果返回
                return courseTypeList;
            }
        }
    }

    logger.debug("从缓存中获取到了数据......");
    //3、如果存在,则将缓存中获取的数据直接返回 - fastjson
    List<CourseType> courseTypeList = JSONArray.parseArray(courseTypes, CourseType.class);
    return courseTypeList;

}

4.3 Avalancha de caché

(1) Caso

Al mismo tiempo, un gran número de cachés falla, lo que hace que las consultas para consultar estas cachés accedan a la base de datos, lo que provoca una presión excesiva de la base de datos;

A diferencia del desglose de la memoria caché, el desglose de la memoria caché es la falla de los "datos activos" (algunas claves),

Una avalancha de caché es donde una gran cantidad de claves fallan al mismo tiempo.

Por ejemplo, cuando se inicia el proyecto, toda la información del usuario se carga desde la base de datos. Establecemos el mismo tiempo de vencimiento. Después de que expira el tiempo, todos estos usuarios han expirado. Todas las solicitudes de consulta del usuario deben acceder a la base de datos (avalancha de caché)

(2) Solución

Haga que el tiempo de vencimiento se distribuya uniformemente (el tiempo de vencimiento coincide con el valor aleatorio y caduca en secuencia dentro de un período de tiempo)

Sexto, curso dentro y fuera de línea + ElasticSearch

1. Breve introducción del negocio en línea y fuera de línea del curso.

  • Después de agregar un nuevo curso en la administración en segundo plano, no quiero que el usuario lo vea de inmediato, necesito esperar a que la fecha en línea de la compañía se conecte a tiempo, por lo que debo conectarme antes de que el usuario pueda buscar.
  • Si un curso ya no se vende por alguna razón, debe desconectarse. Después de desconectarse, los usuarios no pueden ver el curso y ya no pueden comprarlo, pero el curso todavía existe en la base de datos. Si necesita venderlo nuevamente, solo Puede ir en línea

2. ¿Por qué se utilizó Elasticsearch en el proyecto y qué problemas se resolvieron?

  • Cuando los datos del curso están en línea, los datos del curso se sincronizan con es, y el usuario consulta directamente desde es. Esto significa que los usuarios del curso que no están en línea no pueden ser consultados porque no están ubicados en la biblioteca de es.
  • Elimine los datos del curso de la biblioteca es cuando se desconecte. Los usuarios no podrán consultar
  • Alta eficiencia de consulta, soporte de clúster, resolución de un solo punto de falla, soporte de alta concurrencia

Siete, página estática

Proceso de negocio estático de página

  • Después de recibir la solicitud estática de la página, el servicio del curso carga la plantilla estática de la página en fastdfs y obtiene la plantilla devuelta templateFileId;
  • El servicio del curso consulta los antecedentes de los datos que necesita la plantilla, llama al servicio estático de la página a través de fingir y pasa el templateFileId y los datos;
  • Después de recibir estos dos parámetros, el servicio estático de página descarga la plantilla en fastdfs de acuerdo con templateFileId, genera una página estática a partir de la plantilla y los datos, y carga la página en fastdfs para devolver el staticPageFiledId de la página estática;
  • El servicio del curso integra RabbitMq, coloca el staticPageFiledId devuelto por la página estática como un mensaje en el conmutador RabbitMq, y el conmutador distribuye el mensaje a la cola que cumple con lo acordado previamente. El servidor desplegado por el proyecto front-end implementa un programa Java para monitorear la cola RabbitMq para obtener el staticPageFiledId Descargue la página de fastdfs de acuerdo con staticPageFiledId y muéstrela en la página frontal.

Proceso comercial de enviar el código de verificación de SMS

  • Haga clic en el botón para enviar el código de verificación del teléfono móvil, que lleva el código de verificación gráfico y el logotipo uuid y el número de teléfono móvil;

  • El fondo verifica los redis para verificar si el código de verificación gráfico es correcto de acuerdo con uuid, y si no es correcto, devuelve una indicación de que el código de verificación gráfico es incorrecto;

  • El código de verificación gráfico es correcto, consulte la redistribución de acuerdo con el identificador del código de verificación del teléfono móvil (prefijo + número de teléfono móvil) y vea si el número de teléfono móvil tiene un código de verificación de SMS en el caché;

    • Si no existe, genere un código de verificación de SMS, almacene el código de identificación y verificación y la hora en redis, y llame al servicio de SMS para enviar el código de verificación de SMS;
    • Si existe, obtenga el código de verificación de SMS y la hora correspondiente al número de teléfono móvil de redis para determinar si ha expirado. Si no ha expirado, se considera una solicitud ilegal. Sobrescriba los anteriores y llame al servicio para enviar mensajes de texto.

Solución de inicio de sesión único, cómo lograr el inicio de sesión único

  • El front end envía una solicitud de inicio de sesión, y el nombre de usuario y la contraseña se verifican en segundo plano. Después de la verificación, se genera una clave de acceso aleatorio, la información de inicio de sesión se almacena como valor en redis, y se establece el tiempo de vencimiento, y luego la clave de acceso se devuelve al front end;
  • Después de un inicio de sesión exitoso, el front end guarda la clave de acceso devuelta en el token de cookie, que puede ser compartido por otros sitios;
  • El front-end está configurado con un interceptor axios, y si existe un token en cada solicitud, se agrega un token al encabezado de la solicitud;
  • Todas las solicitudes llegarán a la puerta de enlace. Configure un filtro aquí para interceptar las solicitudes a las que se puede acceder solo después de la autenticación. Use el token que se encuentra en el encabezado de la solicitud para consultar si existe redis. Si existe, suéltelo. Si no existe, vuelva a iniciar sesión.

El papel de Zuul Gateway en microservicios

  • Proporcionan un punto de entrada único para todos los microservicios, la puerta de enlace actúa como un aislamiento interno y externo, garantizando la seguridad de los servicios en segundo plano;
  • Identifique los permisos de cada solicitud y rechace las solicitudes que no cumplan con los requisitos; (filtro)
  • Dirige dinámicamente las solicitudes a diferentes clústeres de fondo;
  • Reduzca el acoplamiento entre el cliente y el servicio, el servicio se puede desarrollar de forma independiente y la asignación se realiza a través de la capa de puerta de enlace.
Publicó un artículo original · Me gusta2 · Visitas 59

Supongo que te gusta

Origin blog.csdn.net/weixin_46241579/article/details/105589620
Recomendado
Clasificación