web前端之行为验证码、不同设备和屏幕尺寸呈现不同大小、元素宽度根据视口宽度进行调整、元素或图片裁剪、图片验证码

MENU

  • 前言
  • 版本一(html+JS+css)
  • 版本二(html+JS+css+canvas)


前言

1、版本一的样式比较齐全;
2、版本二的JS逻辑和功能效果比较完善,且是别人的代码,后续会对样式进行完善。[Gitee | 哔哩哔哩];
3、两个版本各有千秋,主要学习里面的一些技巧,这里主要介绍版本一的样式技巧;
4、行为验证码一般是后端实现,而且大概率是使用第三方插件,因为涉及到的逻辑和内容比较多,前后端实现起来都比较麻烦。


版本一(html+JS+css)

案例公共样式

body {
    margin: 0;
    padding: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
}

案例一(clip-path裁剪的应用)

<style>
    .clip_path {
        width: 300px;
        height: 300px;
        background-color: #ff0000;
    }
    
    .clip_path:first-child {
        float: left;
        background-color: #0000ff;
        clip-path: inset(50px 20px 30px 40px round 10px);
    }
</style>

<div>
    <div class="clip_path"></div>
    <div class="clip_path"></div>
</div>

案例一解析

代码块中包含两个<div>元素,每个元素都有类名为clip_path。此外,还有一些CSS样式被应用于这些元素。


CSS样式部分
1、clip_path类指定了一个固定的宽度(300像素)、高度(300像素)和背景颜色(红色)的区域。
2、clip_path:first-child选择器用于选择第一个具有类名clip_path的元素,并对其应用特定样式。
2.1、float: left;将第一个元素左浮动,使其在其右侧的元素之前显示。
2.2、background-color: #0000ff;将第一个元素的背景颜色更改为蓝色。
2.3、clip-path: inset(50px 20px 30px 40px round 10px);将剪切路径应用于第一个元素,剪切路径的形状是一个矩形,内边距为50px 20px 30px 40px,并且角是圆形的,半径为10px。


HTML部分
两个<div>元素被包含在一个外部<div>中。
每个<div>元素都有类名为clip_path,因此它们都受到了相同的CSS样式的影响。


综上所述,代码将显示两个相同大小的红色方块,但第一个方块的背景颜色为蓝色,并具有一种剪切路径,使其内部形成一个圆角矩形区域。


案例一效果图

case11


案例二(clamp最大值最小值的应用)

<style>
	.clamp {
		width: clamp(300px, 50vw, 600px);
		height: 300px;
		background-color: #ff0000;
	}
</style>

<div class="clamp"></div>

案例二解析

一段简单的HTML和CSS代码段,用于创建一个具有限制宽度的元素。


1、<style>标签用于在HTML文档中定义CSS样式。
2、.clamp是一个CSS类选择器,它用于选择具有类名为"clamp"的HTML元素。
3、width: clamp(300px, 50vw, 600px);是一个CSS属性,它使用clamp()函数来设置元素的宽度。clamp()函数接受三个参数,分别是最小宽度、首选宽度和最大宽度。在这个例子中,元素的宽度将被限制在300像素、视窗宽度的50%和600像素之间,以保证在不同设备和屏幕尺寸下有不同的大小。
4、height: 300px;设置元素的高度为300像素。
5、background-color: #ff0000;设置元素的背景颜色为红色。


<div class=“clamp”></div>是一个HTML<div>元素,它具有一个类名为"clamp",因此应用了上述定义的CSS样式。这个<div>元素将具有限制宽度的特性,宽度将根据视窗宽度和定义的最小和最大宽度进行调整,以便在不同设备和屏幕尺寸下呈现出不同的大小。


案例二效果图

case21


case22


功能效果图

imageverificationCodeV11


imageverificationCodeV12


imageverificationCodeV13


html

<div id="captcha">
    <div id="handle">
        <span onmousedown="onmousedownFn()" mousemove="mousemoveFn()"></span>
    </div>
</div>

JavaScript

const captcha = document.querySelector('#captcha');
const handle = document.querySelector('#handle');
const button = document.querySelector('#handle span');
const oLeft = handle.getBoundingClientRect().left;
const buttonWidth = button.getBoundingClientRect().width;
let flag = false;

function onmousedownFn() {
    flag = true;
}

window.addEventListener('mousemove', ({ clientX }) => {
    if (flag) {
        captcha.style.setProperty('--moved', `${clientX - oLeft - buttonWidth / 2}px`);
    }
});

window.addEventListener('mouseup', ({ clientX }) => {
    if (flag) {
        const dis = clientX - oLeft;

        if (dis >= 430 && dis <= 450) {
            captcha.classList.add('passed');
            alert('验证通过!');
        } else {
            captcha.style.setProperty('--moved', '0px');
        }

        flag = false;
    }
});

style

* {
    margin: 0;
    padding: 0;
}

body {
    --width: 400px;
    --height: 260px;
    --puzzle-width: 80px;
    --puzzle-height: 80px;
    --moved: 0px;
    background-color: #008b8b;
    width: 100vw;
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
}

#captcha {
    width: var(--width);
    height: var(--height);
    background-image: url('https://cn.bing.com/th?id=OHR.AlmondBloom_ZH-CN9441550492_1920x1080.jpg');
    background-size: cover;
    background-position: center;
    position: relative;
    border-radius: 4px;
    box-shadow: 0px 2px 4px rgba(0, 0, 0, .3);
}

#captcha::before,
#captcha::after {
    display: flex;
    position: absolute;
    content: '';
    width: inherit;
    height: inherit;
    background-image: inherit;
    background-size: inherit;
    background-position: inherit;
    clip-path: inset( calc((var(--height) - var(--puzzle-height)) / 2) var(--puzzle-width) calc((var(--height) - var(--puzzle-height)) / 2) calc(var(--width) - var(--puzzle-width) * 2));
}

#captcha::after {
    transform: translateX(clamp( calc(var(--width) * -1), calc(var(--width) * -1 + var(--moved)), var(--puzzle-width)));
    transition: .25s all ease-in-out;
    cursor: pointer;
}

#captcha:active::after {
    transition: none;
}

#captcha::before {
    background-color: rgba(0, 0, 0, .6);
    background-blend-mode: multiply;
}

#handle {
    height: 30px;
    width: calc(var(--width) + var(--puzzle-width) * 2);
    border-radius: 18px;
    background-color: #eeeeee;
    box-shadow: inset 0 0 12px rgba(0, 0, 0, .2);
    border: 3px solid #eeeeee;
    position: absolute;
    bottom: -50px;
    left: calc(var(--puzzle-width) * 2 * -1);
}

#handle span {
    width: var(--puzzle-width);
    height: inherit;
    display: block;
    border-radius: inherit;
    background-color: #fff;
    box-shadow: 0 0 6px rgba(0, 0, 0, .25), 0 2px 4px rgba(0, 0, 0, .3);
    cursor: move;
    transform: translateX( clamp( 0px, var(--moved), calc(var(--width) + var(--puzzle-width))));
    cursor: pointer;
    transition: .25s all ease-in-out;
}

#captcha:active #handle span {
    transition: none;
}

#captcha.passed::before,
#captcha.passed::after,
#captcha.passed #handle {
    opacity: 0;
}

版本二(html+JS+css+canvas)

效果图

imageverificationCodeV21


imageverificationCodeV22


imageverificationCodeV23


html

<div class="container">
    <div id="captcha" style="position: relative;"></div>
    <div id="msg"></div>
</div>

<script src="./indexV2.js"></script>
<script>
    captcha.init(document.getElementById('captcha'), function() {
        document.getElementById('msg').innerHTML = '验证成功';
        setTimeout(() => {
            document.getElementById('msg').innerHTML = '';
        }, 2000);
    }, function() {
        document.getElementById('msg').innerHTML = '验证失败';
        setTimeout(() => {
            document.getElementById('msg').innerHTML = '';
        }, 1000);
    })
</script>

JavaScript

(function(win) {
    // 滑块边长
    let l = 42,
        // 滑块半径
        r = 10,
        // canvas宽度
        w = 310,
        //canvas高度
        h = 155,
        PI = Math.PI;
    // 滑块的实际边长
    const ll = l + r * 2;

    // 获取指定区间内的随机数
    function getRandomNumberByRange(start, end) {
        return Math.round(Math.random() * (end - start) + start);
    }

    // 创建元素
    function createElement(tagName) {
        return document.createElement(tagName);
    }

    // 创建画布
    function createCanvas(width, height) {
        const canvas = createElement('canvas');

        canvas.width = width;
        canvas.height = height;

        return canvas;
    }

    // 获取随机图片
    function getRandomImg() {
        // 这个网站可以生成随机图片
        return 'https://picsum.photos/300/150/?image=' + getRandomNumberByRange(0, 100);
    }

    // 创建图片
    function createImg(onload) {
        const img = createElement('img');

        img.crossOrigin = 'Anonymous';
        img.onload = onload;
        img.onerror = () => {
            img.src = getRandomImg();
        }
        img.src = getRandomImg();

        return img;
    }

    // 添加样式
    function addClass(tag, className) {
        tag.classList.add(className);
    }

    // 移除样式
    function removeClass(tag, className) {
        tag.classList.remove(className);
    }

    // 绘制
    function draw(ctx, operation, x, y) {
        ctx.beginPath();
        ctx.moveTo(x, y);
        ctx.lineTo(x + l / 2, y);
        ctx.arc(x + l / 2, y - r + 2, r, 0, 2 * PI);
        ctx.lineTo(x + l / 2, y);
        ctx.lineTo(x + l, y);
        ctx.lineTo(x + l, y + l / 2);
        ctx.arc(x + l + r - 2, y + l / 2, r, 0, 2 * PI);
        ctx.lineTo(x + l, y + l / 2);
        ctx.lineTo(x + l, y + l);
        ctx.lineTo(x, y + l);
        ctx.lineTo(x, y);
        ctx.fillStyle = '#fff';
        ctx[operation]();
        ctx.beginPath();
        ctx.arc(x, y + l / 2, r, 1.5 * PI, 0.5 * PI);
        ctx.globalCompositeOperation = 'xor';
        ctx.fill();
    }

    // 求和
    function sum(x, y) {
        return x + y;
    }

    // 求平方
    function square(x) {
        return x * x;
    }

    // 验证码类
    class captcha {
        // 构造器
        constructor(el, success, fail) {
            this.el = el;
            this.success = success;
            this.fail = fail;
        }

        // 初始化
        init() {
            this.initDOM();
            this.initImg();
            this.draw();
            this.bindEvents();
        }

        // 初始化DOM
        initDOM() {
            const canvas = createCanvas(w, h),
                block = canvas.cloneNode(true),
                sliderContainer = createElement('div'),
                sliderMask = createElement('div'),
                slider = createElement('div'),
                refreshIcon = createElement('div'),
                sliderIcon = createElement('span'),
                text = createElement('span');

            block.className = 'block';
            sliderContainer.className = 'slider-container';
            sliderMask.className = 'slider-mask';
            slider.className = 'slider';
            refreshIcon.className = 'refresh-icon';
            sliderIcon.className = 'slider-icon';
            text.className = 'slider-text';
            text.innerHTML = '向右滑动滑块填充拼图';

            const el = this.el;

            el.appendChild(canvas);
            el.appendChild(refreshIcon);
            el.appendChild(block);
            slider.appendChild(sliderIcon);
            sliderMask.appendChild(slider);
            sliderContainer.appendChild(sliderMask);
            sliderContainer.appendChild(text);
            el.appendChild(sliderContainer);

            Object.assign(this, {
                canvas,
                block,
                sliderContainer,
                refreshIcon,
                slider,
                sliderMask,
                sliderIcon,
                text,
                canvasCtx: canvas.getContext('2d'),
                blockCtx: block.getContext('2d')
            });
        }

        // 初始化图像
        initImg() {
            const img = createImg(() => {
                this.canvasCtx.drawImage(img, 0, 0, w, h);
                this.blockCtx.drawImage(img, 0, 0, w, h);
                const y = this.y - r * 2 + 2;
                const imageData = this.blockCtx.getImageData(this.x, y, ll, ll);
                this.block.width = ll;
                this.blockCtx.putImageData(imageData, 0, y);
            });

            this.img = img;
        }

        // 绘画
        draw() {
            this.x = getRandomNumberByRange(ll + 10, w - (ll + 10));
            this.y = getRandomNumberByRange(10 + r * 2, h - (ll + 10));

            draw(this.canvasCtx, 'fill', this.x, this.y);
            draw(this.blockCtx, 'clip', this.x, this.y);
        }

        // 清除
        clean() {
            this.canvasCtx.clearRect(0, 0, w, h);
            this.blockCtx.clearRect(0, 0, w, h);
            this.block.width = w;
        }

        // 绑定事件
        bindEvents() {
            this.el.onselectstart = () => false;
            this.refreshIcon.onclick = () => {
                this.reset();
            }

            let originX, originY, trail = [],
                isMouseDown = false;

            this.slider.addEventListener('mousedown', function(e) {
                originX = e.x;
                originY = e.y;
                isMouseDown = true;
            });
            document.addEventListener('mousemove', (e) => {
                if (!isMouseDown) return false;

                const moveX = e.x - originX;
                const moveY = e.y - originY;

                if (moveX < 0 || moveX + 38 >= w) return false;
                this.slider.style.left = moveX + 'px';
                var blockLeft = (w - 40 - 20) / (w - 40) * moveX;
                this.block.style.left = blockLeft + 'px';
                addClass(this.sliderContainer, 'slider-container-active');
                this.sliderMask.style.width = moveX + 'px';
                trail.push(moveY);
            });
            document.addEventListener('mouseup', (e) => {
                if (!isMouseDown) return false;
                isMouseDown = false;
                if (e.x == originX) return false;
                removeClass(this.sliderContainer, 'slider-container-active');
                this.trail = trail;

                const spliced = this.verify();

                if (spliced) {
                    addClass(this.sliderContainer, 'slider-container-success');
                    this.success && this.success();
                } else {
                    addClass(this.sliderContainer, 'slider-container-fail');
                    this.fail && this.fail();
                    setTimeout(() => {
                        this.reset();
                    }, 1000);
                }
            });
        }

        // 重置
        reset() {
                this.sliderContainer.className = 'slider-container';
                this.slider.style.left = 0;
                this.block.style.left = 0;
                this.sliderMask.style.width = 0;
                this.clean();
                this.img.src = getRandomImg();
                this.draw();
            }
            // 验证
        verify() {
            const left = parseInt(this.block.style.left);
            //10表示容错率,值越小,需要拼得越精确
            return Math.abs(left - this.x) < 10;
        }
    }

    win.captcha = {
        init: function(element, success, fail) {
            new captcha(element, success, fail).init();
        }
    }
}(window));

style

* {
    margin: 0;
    padding: 0;
    background-color: #333333;
}

body {
    /* 方便演示,满屏居中 */
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
}


/* 小拼图 */

.block {
    position: absolute;
    left: 0;
    top: 0;
}


/* 滑动条 */

.slider-container {
    position: relative;
    text-align: center;
    width: 310px;
    height: 40px;
    line-height: 40px;
    margin-top: 15px;
    background-color: #f7f9fa;
    color: #45454c;
    border: 1px solid #e4e7eb;
}

.slider-mask {
    position: absolute;
    left: 0;
    top: 0;
    height: 40px;
    border: 0px solid #1991fa;
    background-color: #d1e9fe;
}

.slider {
    position: absolute;
    left: 0;
    top: 0;
    width: 40px;
    height: 40px;
    background: #fff;
    box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);
    cursor: pointer;
    transition: background 0.2s linear;
}

.slider-icon {
    position: absolute;
    left: 13px;
    top: 15px;
    width: 14px;
    height: 10px;
    background: url(/images/icon_light.png) 0 -26px;
    background-size: 34px 471px;
}


/* 滑动条活动态 */

.slider-container-active .slider {
    height: 38px;
    top: -1px;
    border: 1px solid #1991fa;
}

.slider-container-active .slider-mask {
    height: 38px;
    border-width: 1px;
}


/* 滑动条成功态 */

.slider-container-success .slider {
    height: 38px;
    top: -1px;
    border: 1px solid #52ccba;
    background-color: #52ccba !important;
}

.slider-container-success .slider-mask {
    height: 38px;
    border: 1px solid #52ccba;
    background-color: #d2f4ef;
}


/* 成功图标 */

.slider-container-success .slider-icon {
    background-position: 0 0 !important;
}


/* 滑动条失败态 */

.slider-container-fail .slider {
    height: 38px;
    top: -1px;
    border: 1px solid #f57a7a;
    background-color: #f57a7a !important;
}

.slider-container-fail .slider-mask {
    height: 38px;
    border: 1px solid #f57a7a;
    background-color: #fce1e1;
}


/* 失败图标 */

.slider-container-fail .slider-icon {
    background-position: 0 -83px !important;
}

.slider-container-active .slider-text,
.slider-container-success .slider-text,
.slider-container-fail .slider-text {
    display: none;
}

.slider:hover {
    background: #1991fa;
}

.slider:hover .slider-icon {
    background-position: 0 -13px;
}

.refresh-icon {
    position: absolute;
    right: 0;
    top: 0;
    width: 34px;
    height: 34px;
    background: url(/images/icon_light.png) 0 -437px;
    background-size: 34px 471px;
    cursor: pointer;
}

#msg {
    height: 20px;
    line-height: 20px;
    text-align: center;
    margin-top: 15px;
}

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

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

相关文章

使用 ArcGIS Pro 和 Google Earth Engine 可视化地表温度

在这项研究中,利用 Landsat 热数据通过各种方法检查了 2013 年和 2023 年恰纳卡莱省的地表温度变化。使用了 NDVI、大气层顶部、亮度温度、植被比例和地表温度等公式。研究结果表明,从热图像中获得的数据,特别是地表温度(LST),是土地解释的重要资源。 研究区域:恰纳卡莱…

[Java、Android面试]_14_Retrofit的作用

本人今年参加了很多面试&#xff0c;也有幸拿到了一些大厂的offer&#xff0c;整理了众多面试资料&#xff0c;后续还会分享众多面试资料。 整理成了面试系列&#xff0c;由于时间有限&#xff0c;每天整理一点&#xff0c;后续会陆续分享出来&#xff0c;感兴趣的朋友可关注收…

2024 年广西职业院校技能大赛高职组《云计算应用》赛项赛题第 2 套

#需要资源或有问题的&#xff0c;可私博主&#xff01;&#xff01;&#xff01; #需要资源或有问题的&#xff0c;可私博主&#xff01;&#xff01;&#xff01; #需要资源或有问题的&#xff0c;可私博主&#xff01;&#xff01;&#xff01; 某企业根据自身业务需求&…

电脑数据守护神:自动备份数据的重要性与实用方案

一、数据安全的基石&#xff1a;自动备份数据的重要性 在数字化时代&#xff0c;电脑中的数据成为了我们生活和工作中不可或缺的一部分。无论是重要的工作文件、珍贵的个人照片&#xff0c;还是日常使用的应用程序&#xff0c;这些数据都承载着我们的记忆和劳动成果。然而&…

学习次模函数-第1章 引言

许多组合优化问题可以被转换为集合函数的最小化&#xff0c;集合函数是在给定基集合的子集的集合上定义的函数。同样地&#xff0c;它们可以被定义为超立方体的顶点上的函数&#xff0c;即&#xff0c;其中是基集合的基数-它们通常被称为伪布尔函数[27]。在这些集合函数中&…

taro框架之taro-ui中AtSwipeAction的使用

题记&#xff1a;所需效果&#xff1a;滑动删除 工作进程 官网文档代码 <AtSwipeAction options{[{text: 取消,style: {backgroundColor: #6190E8}},{text: 确认,style: {backgroundColor: #FF4949}} ]}><View classNamenormal>AtSwipeAction 一般使用场景</…

【Linux】进程地址空间详解

前言 在我们学习C语言或者C时肯定都听过老师讲过地址的概念而且老师肯定还会讲栈区、堆区等区域的概念&#xff0c;那么这个地址是指的物理内存地址吗&#xff1f;这里这些区域又是如何划分的呢&#xff1f; 我们在使用C语言的malloc或者C的new函数开辟空间时&#xff0c;开辟…

FreeRTOS(二)

第一部分 信号量 &#xff08;一&#xff09;信号量的本质 首先我们先来看队列的结构体&#xff0c;我们不难发现队列结构体中说到有个联合体在用于队列时&#xff0c;使用Queue&#xff0c;在用于信号量时&#xff0c;使用XSemaphore。后面又说到了一些对列的类型&#xff0…

简述C语言文件操作

&#x1f308; 个人主页&#xff1a;白子寰 &#x1f525; 分类专栏&#xff1a;魔法指针&#xff0c;进阶C&#xff0c;C语言&#xff0c;C语言题集&#xff0c;C语言实现游戏&#x1f448; 希望得到您的订阅和支持~ &#x1f4a1; 坚持创作博文(平均质量分79)&#xff0c;分享…

逻辑运算符、#define易错点

文章目录 逻辑运算符#define易错点 一、逻辑运算符 #include<stdio.h> #define PERIOD . int main() {char ch;int charcount0;while((chgetchar())!PERIOD){if(ch!"&&ch!\)charcount;}printf("There are %d non-quote characters.\n",charcount…

算法---动态规划练习-1(三步问题)

三步问题 1. 题目解析2. 讲解算法原理3. 编写代码 1. 题目解析 题目地址&#xff1a;三步问题 2. 讲解算法原理 1. 定义一个常量MOD为10^97&#xff0c;用于取模运算。 2. 创建一个长度为n3的数组dp&#xff0c;用于存储计算过程中的中间结果。数组的下标表示台阶的级数&…

扩展一下BenchmarkSQL,新增支持ASE/HANA/DB2/SQLServer,可以随便用了

1 背景 提到数据库的性能,自然就避不开性能测试。有专用于测试OLTP的,也有偏重于OLAP的。本文介绍的BenchmarkSQL就属于测试OLTP中的一个,基于TPCC的。网上有很多介绍TPC*的相关测试的文章,大家可以自行脑补。而PostgreSQL自带的pgbench是属于TPCC的前一个基准测试程序,偏…

【vue核心技术实战精讲】1.3 - 1.6 VUE 指令 (上)

前言 上节,我们学习了 Vue的起步 和 插值表达式 本节内容 Vue指令之v-text 和 v-htmlVue指令之v-if 和 v-showVue指令之v-bind绑定Vue指令之v-on事件处理 1、v-text 和 v-html {{}} 和v-text的作用是一样的 都是插入值,直接渲染 ≈ innerTextv-html既能插入值 又能插入标签…

Linux下安装redis

1、redis的编译环境 Redis是C语言开发的&#xff0c;安装redis需要先去官网下载源码进行编译&#xff0c;编译需要依赖于GCC编译环境&#xff0c;如果CentOS上没有安装gcc编译环境&#xff0c;需要提前安装&#xff0c;安装命令如下:&#xff08;这里我们使用root用户处理这些…

linux 区别:mount 一个目录到另外一个目录,目录软链接 (*)

Linux命令200例&#xff1a;mount将文件系统挂载到指定目录下&#xff08;常用&#xff09; https://blog.csdn.net/qq_21891743/article/details/132220283 Linux磁盘卸载 https://blog.csdn.net/Mcy7ycM/article/details/124347504 能否通俗易懂&#xff0c;深入浅出地解释…

Zabbix使用TimescaleDB数据库

一、前言 Zabbix 6.0 已发布很久&#xff0c;下个季度7.0应该会正式发布&#xff0c;但6.0也有许多新功能和新特性&#xff0c;这里介绍 6.0 配置 TimescaleDB&#xff0c;此安装配置方法可基本通用与其他版本。 二、TimescaleDB TimescaleDB 基于 PostgreSQL 数据库打造的一…

MySQL数据库 - 单表查询(三)

一个不知名大学生&#xff0c;江湖人称菜狗 original author: Jacky Li Email : 3435673055qq.com Time of completion&#xff1a;2024.03.24 Last edited: 2024.03.24 目录 第1关&#xff1a;对查询结果进行排序 任务描述 相关知识 对查询结果排序 指定排序方向 编程要…

需求分析的过程

需求分析的工具 ominGraffle/Visio Gliffy ProcessOn RSA(UML) PPT/WORD 手绘 需求所需要的工件&#xff1a; 系统上下文、用例模型、质量限制 1.系统上下文的工件 2.用例模型工件&#xff08;什么功能&#xff09; 3.质量和限制 质量&#xff1a;管理10个小动物&#xff0c;…

注册中心的基础知识

什么是注册中心 当服务启动时,将服务信息服务名称/IP/端口写入注册中心.注册中心接收服务端信息时保存服务信息,并且维护服务列表数据当服务消费者启动时会通过IP:端口(注册中心)远程链接注册中心. 获取服务列表信息.缓存到本地 当消费者调用服务时,查找缓存到本地的服务列表…

Druid连接池的能力介绍与使用方法

Druid连接池的能力介绍与使用方法 本文将介绍druid连接池的能力&#xff1a;监控sql调用数据&#xff08;慢sql、调用量、异常堆栈&#xff09;、防止sql注入和数据库密码加密。 1. Druid连接池简介 Alibaba Druid官网使用手册里是这样介绍的&#xff1a;Druid连接池是阿里巴…
最新文章