【技术分享】使用nginx完成动静分离➕集成SpringSession➕集成sentinel➕集成seata

news2025/1/18 10:06:46

🥳🥳Welcome 的Huihui's Code World ! !🥳🥳

接下来看看由辉辉所写的关于技术点的相关分享吧

目录

🥳🥳Welcome 的Huihui's Code World ! !🥳🥳

一、 使用nginx完成动静分离

1.下载nginx

2.进入conf目录,并修改nginx.conf配置文件

3.动静分离

4.将静态文件放置再nginx中

5.运行nginx根目录下的nginx.exe启动nginx

6.修改项目中静态资源的路径

二、 集成SpringSession

1.引入依赖

2.在需要使用到springsession的模块做以下配置

3.编写代码完成登录功能

4.前端显示

三、 集成sentinel

1.导入pom依赖

2.在application文件中进行配置

3.浏览器访问sentinel

四、集成seata

1.下载seata

2.修改配置文件及初始化

①seata-server-1.4.0.zip​​​​​​​

②修改file.conf

③创建数据库Seata并初始化数据表

3.启动seata服务

4.使用Seata实现事务控制

1.初始化数据表

2.添加配置

①DataSourceProxyConfig

②application.yml

③registry.conf

③bootstrap.yaml


一、 使用nginx完成动静分离

1.下载nginx

2.进入conf目录,并修改nginx.conf配置文件

其中也可以完成反向代理的功能


#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    
    server
	{
		listen 80;
		server_name product.zmall.com;
		proxy_redirect off;
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		
		location / {
			proxy_pass http://127.0.0.1:8000/product-serv/;
		}
	}

	server
	{
		listen 80;
		server_name user.zmall.com;
		proxy_redirect off;
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		client_max_body_size 0; 
		chunked_transfer_encoding on;
		location / {
			proxy_pass http://127.0.0.1:8000/user-serv/;
		}
	}
    

}

3.动静分离

server
	{
		listen 80;
		server_name images.zmall.com;
		
		location / {
		    root  html;
		    index index.html;
		}
	}

4.将静态文件放置再nginx中

5.运行nginx根目录下的nginx.exe启动nginx

6.修改项目中静态资源的路径

我使用了一个公共的文件,再里面使用了一个base标签,这样其他页面引用这个文件就可以用到其中的静态资源了。

<#assign ctx>
${springMacroRequestContext.contextPath}/
</#assign>
<base href="http:images.zmall.com/"/>

这里的域名也需要做一个域名映射

C:\Windows\System32\drivers\etc\hosts

二、 集成SpringSession

使用其来完成登录成功之后,在首页显示当前用户信息【跨服务】

1.引入依赖

<!--redis-->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--spring session-->
<dependency>
	<groupId>org.springframework.session</groupId>
	<artifactId>spring-session-data-redis</artifactId>
</dependency>
<!--commons-pool2-->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

2.在需要使用到springsession的模块做以下配置

spring:
  session:
    redis:
      flush-mode: on_save
      namespace: session.zmall
      cleanup-cron: 0 * * * * *
    store-type: redis
    timeout: 1800
  redis:
    host: localhost
    port: 6379
    password: 123456
    jedis:
      pool:
        max-active: 100
        max-wait: 10
        max-idle: 10
        min-idle: 10
    database: 0

3.编写代码完成登录功能

package com.wh.user.service.impl;

import com.alibaba.nacos.common.utils.MD5Utils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wh.user.pojo.User;
import com.wh.user.mapper.UserMapper;
import com.wh.user.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wh.user.utils.JsonResponseBody;
import com.wh.user.utils.JsonResponseStatus;
import com.wh.user.vo.UserVo;
import dto.UserDto;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author baomidou
 * @since 2024-02-21
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

/**
 * 登录
 * @param userVo
 * @return
 */
    @Override
    public JsonResponseBody<?> userLogin(UserVo userVo) {
        //通过传递过来的用户名去数据库中查询对应的对象
        User user = this.getOne(new QueryWrapper<User>().eq("loginName", userVo.getLoginName()));
        //做密码判断【数据库的密码是经过加密的】
        //将用户传递过来的密码加密
        String userpwd = DigestUtils.md5DigestAsHex(userVo.getPassword().getBytes());
        //加密之后与数据库中的用户密码进行对比
        if(!userpwd.equals(user.getPassword())){
            //如果密码不匹配,则提示相关错误信息
            return JsonResponseBody.other(JsonResponseStatus.LOGIN_NO_EQUALS);
        }
        //如果登录成功,就进行属性复制
        UserDto userDto = new UserDto();
        //属性复制
        BeanUtils.copyProperties(user,userDto);
        return JsonResponseBody.success();
    }

}
package com.wh.user.controller;

import com.wh.user.service.IUserService;
import com.wh.user.utils.JsonResponseBody;
import com.wh.user.vo.UserVo;
import dto.UserDto;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author baomidou
 * @since 2024-02-21
 */
@RestController
public class UserController {
    @Autowired
    private IUserService userService;
    @Autowired
    private HttpServletRequest request;
    /**
     * 用户登陆功能实现
     * @return
     */
    @RequestMapping("/userLogin")
    public JsonResponseBody<?> userLogin(UserVo userVo){
        //设置当前用户的登录信息
        request.getSession().setAttribute("user",userVo);
        //调用登录的方法
        JsonResponseBody<?> user = userService.userLogin(userVo);
        return user;
    }
}

在跳首页的controller方法中获取当前登录用户的session信息

@Autowired
    private IProductService productService;
    @Autowired
    private HttpServletRequest request;
    /**
     * 首页跳转
     * @param model
     * @return
     */
    @RequestMapping("/index.html")
    public String index(Model model){
        //获取当前用户的登录信息
        UserDto user = (UserDto)request.getSession().getAttribute("user");
        //按照商品的销量降序排序获取销量排名Top5的商品
        List<Product> products = productService.list(new QueryWrapper<Product>()
                .orderByDesc("hot")
                .last("limit 4"));
        model.addAttribute("top4",products);
        model.addAttribute("user",user);
        return "Index";
    }

4.前端显示

<div class="soubg">
	<div class="sou">
        <span class="fr">
        	<span class="fl">你好,
                <#if user??>
                    ${user.loginName}
                    <#else><a href="Login.html">请登录</a>
                </#if>
                &nbsp; <a href="Regist.html" style="color:#ff4e00;">免费注册</a>&nbsp; </span>
            <span class="fl">|&nbsp;关注我们:</span>
            <span class="s_sh"><a href="#" class="sh1">新浪</a><a href="#" class="sh2">微信</a></span>
            <span class="fr">|&nbsp;<a href="#">手机版&nbsp;<img src="images/s_tel.png" align="absmiddle" /></a></span>
        </span>
    </div>
</div>

三、 集成sentinel

1.导入pom依赖

到网关中

<!-- sentinel -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>

2.在application文件中进行配置

sentinel:
      transport:
        port: 9998 #跟控制台交流的端口,随意指定一个未使用的端口即可
        dashboard: localhost:9999 # 指定控制台服务的地址
      eager: true #当服务启动时是否与sentinel建立连接
      web-context-unify: false # 关闭URL PATH聚合

3.浏览器访问sentinel

在此之前需要启动sentinel的那个jar包

# 直接使用jar命令启动项目(控制台本身是一个SpringBoot项目)
java -Dserver.port=9999 -Dcsp.sentinel.dashboard.server=localhost:9999 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.4.jar

四、集成seata

1.下载seata

下载地址icon-default.png?t=N7T8http://Release v1.3.0 · apache/incubator-seata · GitHubRelease v1.3.0 · apache/incubator-seata · GitHub

2.修改配置文件及初始化

①seata-server-1.4.0.zip

将下载得到的seata-server-1.4.0.zip(非源码包)压缩包进行解压

  • 配置seata-1.4.0.zip(源码包)

修改seata-1.4.0中script/config-center目录中的config.txt配置:

store.mode=db    #修改存储方式为db
...
store.db.url=jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true   #修改数据库名
store.db.user=root      #修改数据库账号
store.db.password=1234  #修改数据库密码
  • 初始化Seata配置到Nacos中

在seata-1.4.0\script\config-center\nacos目录中右键选择git bash here,运行git命令窗口。并输入以下命令:

sh nacos-config.sh -h localhost -p 8848 -g SEATA_GROUP -u nacos -w nacos
参数说明
-hnacos注册中心IP地址,默认是localhost
-pnacos注册中心端口,默认是8848
-gnacos配置中心分组,默认是SEATA_GROUP
-tnacos配置中心namespace命名空间名称,默认是'',即public默认命名空间
-unacos注册中心账号
-wnacos注册中心密码

执行成功后可以打开Nacos的控制台,在配置列表中,可以看到初始化了很多Group为SEATA_GROUP 的配置。

②修改file.conf

将mode=“type”修改成mode="db" 2.设置数据库名、用户账号及密码

③创建数据库Seata并初始化数据表

解压seata-1.4.0源码包,并进入到seata-1.4.0\script\server\db目录,复制运行mysql.sql脚本完成seata服务端数据库初始化工作。【记得先创建一个数据库:seata】

④修改registry.conf

registry {
    type = "nacos"                     #这里使用nacos为注册中心,将type修改成nacos
    nacos {
        application = "seata-server"   #注册的服务名
        serverAddr = "127.0.0.1:8848"  #nacos注册中心地址及端口
        group = "SEATA_GROUP" #服务注册分组
        namespace = ""        #namespace是服务注册时的命名空间,可不填,不填默认public
        cluster = "default"   #默认即可
        username = "nacos"    #nacos的登录账号
        password = "nacos"    #nacos的登录密码
    }
}
config {
    type = "nacos"
    nacos {
        serverAddr = "127.0.0.1:8848"
        namespace = ""
        group = "SEATA_GROUP"
        username = "nacos"
        password = "nacos"
    }
}

registry:指定注册中心,将seata-server注册到指定位置 config: 指定配置中心

3.启动seata服务

直接进入seata服务的seata\bin目录下,双击运行seata-server.bat文件即可。或者使用以下命令方式运行:

cd bin
seata-server.bat -p 9000 -m file
seata-server.bat -h ip地址 -p 9000 -m file

-p 9000:指定监听端口,默认为8091

-m file: 模式

启动后在 Nacos 的服务列表下面可以看到一个seata的服务。

4.使用Seata实现事务控制

1.初始化数据表

进入源码包seata-1.4.0\script\client\at\db目录,复制并运行数据库脚本完成undo_log表创建,这是Seata记录事务日志要用到的表。

CREATE TABLE `undo_log`
(
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`branch_id` BIGINT(20) NOT NULL,
`xid` VARCHAR(100) NOT NULL,
`context` VARCHAR(128) NOT NULL,
`rollback_info` LONGBLOB NOT NULL,
`log_status` INT(11) NOT NULL,
`log_created` DATETIME NOT NULL,
`log_modified` DATETIME NOT NULL,
`ext` VARCHAR(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = INNODB
AUTO_INCREMENT = 1
DEFAULT CHARSET = utf8;

2.添加配置

①DataSourceProxyConfig
package com.zking.zmall.config;

import com.alibaba.druid.pool.DruidDataSource;
import io.seata.rm.datasource.DataSourceProxy;
import io.seata.rm.datasource.xa.DataSourceProxyXA;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;

@Configuration
public class DataSourceProxyConfig {
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DruidDataSource druidDataSource() {
        return new DruidDataSource();
    }

    @Primary
    @Bean("dataSourceProxy")
    public DataSource dataSource(DruidDataSource druidDataSource) {
        //AT模式
        return new DataSourceProxy(druidDataSource);
        //XA模式
        //return new DataSourceProxyXA(druidDataSource);
    }
}

在启动类(使用到SeaTa)上排除DataSource数据源自动配置类

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
②application.yml

在需要进行分布式事务的各个微服务中的application.yml数据源更新成阿里巴巴的DruidDataSource

#type连接池类型 DBCP,C3P0,Hikari,Druid,默认为Hikari
    type: com.alibaba.druid.pool.DruidDataSource
③registry.conf

在微服务模块中的resources目录下添加seata的配置文件 registry.conf,该配置文件来自于seata-server/conf目录下的配置文件。

registry {
    type = "nacos"
    nacos {
        serverAddr = "localhost"
        namespace = "public"
        cluster = "default"
    }
}
config {
    type = "nacos"
    nacos {
        serverAddr = "localhost"
        namespace = "public"
        cluster = "default"
    }
}
③bootstrap.yaml

请注意spring.cloud.alibaba.seata.tx-service-group=my_test_txgroup配置。这里的my_test_tx_group名称必须与seata源码包中的config.txt配置文件中的名字一致。重要,重要,重要!!!

请打开seata源码包目录seata-1.4.0\script\config-center\下的config.txt去进行配置。

spring:
  application:
    name: service-product
  cloud:
    nacos:
      config:
        server-addr: localhost:8848 # nacos的服务端地址
        namespace: public
        group: SEATA_GROUP
    alibaba:
      seata:
        tx-service-group: my_test_tx_group

注意:一定要加一个配置

<!--bootstrap文件的配置-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>

好啦,今天的分享就到这了,希望能够帮到你呢!😊😊 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构2月25日

第一道&#xff1a; 第二道&#xff1a; 1、插入到prev和next中间 1.new(struct list_head*)malloc(sizeof(struct list_head*)); if(newNULL) { printf("失败\n"); return; } new->nextprev->next; prev->nextnew; return; 2、删除prve和next…

day4:对话框与事件

使用qt搭建一个简易的闹钟系统 #include "second.h" #include "ui_second.h"second::second(QWidget *parent) :QWidget(parent),ui(new Ui::second) {ui->setupUi(this);this->setWindowFlag(Qt::FramelessWindowHint);this->setAttribute(Qt::…

2023年总结与2024展望

今天是春节后上班第一天&#xff0c;你懂的&#xff0c;今天基本上是摸鱼状态&#xff0c;早上把我们负责的项目的ppt介绍完善了一下&#xff0c;然后写了一篇技术文章&#xff0c;《分布式系统一致性与共识算法》。接着就看了我近几年写的的年度总结&#xff0c;我一般不会在元…

数据结构知识点总结-线性表(1)-线性表的定义、基本操作、顺序表表示

线性表 定义 线性表是具有相同数据类型的N&#xff08;N>0&#xff09;个元素的有限序列&#xff0c;其中N为表长&#xff0c;当N0时线性表是一张空表。 线性表的逻辑特征&#xff1a;每个非空的线性表都有一个表头元素和表尾元素&#xff0c;中间的每个元素有且仅有一个直…

stm32利用CubeMX实现外部中断触发数码管加减数

首先打开proteus绘制电路图&#xff0c;如下&#xff1a; 然后打开CubeMX&#xff0c;配置晶振和GPIO&#xff1a; 接下来就是生成keil工程文件&#xff0c;用keil打开。 新建一个desplay.h文件&#xff1a;下面是全部代码 #ifndef __DESPLAY_H #define __DESPLAY_H #endif#i…

python 3.11中安装sympy(符号工具包)

1.python环境&#xff1a; 2.安装遇到问题&#xff1a; … 3.升级pip cmd命令行中&#xff0c;执行如下命令&#xff1a; python.exe -m pip installl --upgrade pip 4.再次安装sympy cmd命令行中&#xff0c;执行如下命令&#xff1a; pip install sympy 5.简单应用 对…

手把手教你Jenkins整合Jmeter实现自动化接口测试!

01、在机器上安装jmeter 下载&#xff1a;http://jmeter.apache.org/download_jmeter.cgi 这里我用了一台Windows安装jmeter用来写接口测试的脚本&#xff0c;启动前修改jmeter.properties 中 jmeter.save.saveservice.output_format值为xml。 编写接口测试脚本&#xff1a; 脚…

OpenGL ES (OpenGL) Compute Shader 计算着色器是怎么用的?

OpenGL ES (OpenGL) Compute Shader 是怎么用的? Compute Shader 是 OpenGL ES(以及 OpenGL )中的一种 Shader 程序类型,用于在GPU上执行通用计算任务。与传统的顶点着色器和片段着色器不同,Compute Shader 被设计用于在 GPU 上执行各种通用计算任务,而不是仅仅处理图形…

Apache DolphinScheduler 3.2.1 版本发布:增强功能与安全性的全面升级

近期&#xff0c;Apache DolphinScheduler 社区激动地宣布 3.2.1 版本的发布。此次更新不仅着力解决了前一版本&#xff08;3.2.0&#xff09;中遗留的问题&#xff0c;而且引入了一系列的功能增强和优化措施。 原先的问题主要源于部分重要代码在发布过程中未能成功合并&#x…

LabVIEW储氢材料循环寿命测试系统

LabVIEW储氢材料循环寿命测试系统 随着氢能技术的发展&#xff0c;固态储氢技术因其高密度和安全性成为研究热点。储氢材料的循环寿命是衡量其工程应用的关键。然而&#xff0c;传统的循环寿命测试设备存在成本高、测试效率低、数据处理复杂等问题。设计了一种基于LabVIEW软件…

深度学习系列59:文字识别

1. 简单文本&#xff1a; 使用google加的tesseract&#xff0c;效果不错。 首先安装tesseract&#xff0c;在mac直接brew install即可。 python调用代码&#xff1a; import pytesseract from PIL import Image img Image.open(1.png) pytesseract.image_to_string(img, lan…

Java的加密的字段模糊查询

Java的加密的字段模糊查询 1.对于加密字段查询不是很友好&#xff0c;但有这样的需求的&#xff0c;本文提供以下思路 2.如何对加密后的数据进行模糊查询 我整理了一下对加密的数据模糊查询大致分为三类做法&#xff0c;如下所示&#xff1a; 沙雕做法&#xff08;不动脑思考…

k8s(4)

目录 负载均衡部署 做初始化操作&#xff1a; 每台主机添加域名 从 master01 节点上拷贝证书文件、各master组件的配置文件和服务管理文件到 master02 节点: 修改02配置文件kube-apiserver&#xff0c;kube-controller-manager&#xff0c;kube-scheduler中的IP&#xff1…

魔改Mac OS渗透测试工具箱!

简介 本工具箱为v1版本&#xff0c;由"森然"师傅进行二开。 通过Python进行调用&#xff0c;并实现图形化界面。 参考&#xff1a;狐狸工具箱&#xff0c;闲客工具箱 环境以及工具 综合了常用的几个工具 适配Mac、Windos、Linux用户 注意&#xff1a;自带的jav…

软件运维维保服务方案-套用模板

软件运维维保方案-套用模板 项目情况 1.1 项目背景简述项目的来源、目的和重要性。说明项目的规模、预算和预期目标。 1.2 项目现状分析当前系统/软件的运行状态、存在的问题和潜在风险。提供最近一次的维护报告或相关统计数据。服务简述 2.1 服务内容明确运维服务的具体内容&…

网站开发--Cookie 和 Session 的工作流程

&#x1f495;"Echo"&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;网站开发–Cookie 和 Session 的工作流程 一.Cookie和Session的基本概念 前言:HTTP协议是无状态协议 无状态协议就是指HTTP协议在传输的过程中不会保存上一次交互的状态信息,但是…

Linux之用户跟用户组

目录 一、简介 1.1、用户 1.2用户组 1.3UID和GID 1.4用户账户分类 二、用户 2.1、创建用户&#xff1a;useradd 2.2、删除用户&#xff1a;userdel 2.3 、修改用户 usermod 2.4、用户口令的管理:passwd 2.5、切换用户 三、用户组 3.1、增加一个用户组:groupadd 3.…

Makefile静态库动态库的构建和链接之工程实用篇

静态库和动态库的构建和链接 现有C工程目录结构如下&#xff1a; add.h int add(int a, int b);add.cpp #include "add.h"int add(int a, int b) {return ab; }main.cpp #include <iostream> #include "add.h"int main() {std::cout << a…

数据结构-二分搜索树(Binary Search Tree)

一,简单了解二分搜索树 树结构: 问题:为什么要创造这种数据结构 1,树结构本身是一种天然的组织结构,就好像我们的文件夹一样,一层一层的. 2,树结构可以更高效的处理问题 二,二分搜索树的基础 1、二叉树 2,二叉树的重要特性 满二叉树 总结: 1. 叶子结点出现在二叉树的最…

Python习题详解

练习&#xff1a; 1&#xff0c;计算100以内奇数的和 #计算100以内所有奇数的和 sum 0 # n 1 # while n < 100: # # sum sum n # sum n # # n n 2 # n 2 # print(sum) n 99 #求偶数时n 100 while n > 0:sum n# n n - 2n - 2 print(sum)2&#xff0c;打印直…