当前位置: 首页 > news >正文

短URL服务设计

引言

在营销系统里,为了增加系统的活跃用户数,经常会有各种各样的营销活动。这类活动几乎都是为了充分利用存量用户的价值,促使他们分享产品或App以达到触达到更多用户的目的。又或者是出于营销目的,群发优惠券触达短信这种场景。

分享App活动页(或其他各种页面)时URL一般会带有各种参数,比如分享者fromUserId,涉及活动campaignId,分享源头类型sourceType等,还有其他各种和具体业务场景挂钩的参数,一个URL动辄300~400个字符。显然,这么长的URL看得头大,而且除了开发者或黑客可能没有人关心URL里具体有什么参数。期望分享出去的URL是一些更短、更易于阅读的短URL。

假设使用阿里云短信发送平台。在群发短信的场景下,假设需要发送10w条短信。短信付费有按数量付费,和套餐包两种形式,一般而言,在待发送的短信数量较大时,套餐包比按量付费来得优惠。大致看一下套餐包价格表:
在这里插入图片描述
还是一笔不小的开支。

因此,如果要把活动链接URL几百个字符通过短信来发送,明显会超过短信发送长度限制。阿里云的短信内容有长度限制:
在这里插入图片描述
就算不考虑短信付费问题。在短信内容超长后需拆分发送的规则下,长链接URL被拆分为多个短信发送,URL会被截断,就不是正确的URL。

上面洋洋洒洒说了这么多,甚至有愚蠢的嫌疑,无非是想引出本文的主题。

我们需要一个端URL服务。当短信触达用户(被分享用户)点击这个短URL时,可以重定向访问到原始的长URL地址。比如https://t.cn/A12afD就是我随便写的一个短链,其中https://t.cn/是新浪微博申请的域名。后面的6位随机字符就是精简后的短URL,区分大小写,使用a-z,A-Z,0-9共62个字符。严谨来说,长URL对应的短URL实际上指的是A12afD;域名(https://t.cn/)+精简后端URL字符(A12afD)共同组成一个可点击的链接地址。

简介

短URL服务,也有叫做短链服务,短链接生成器。当客户端(服务请求者,发起方,调用者)请求端URL服务时,短URL服务返回一个或多个短URL。用户浏览器(PC、App、H5等)点击URL时,可以自动访问原始长URL对应的目标服务。

一个简单的涉及到4个模块(子系统)的时序图如下:
在这里插入图片描述
流程分析:对于需要展示短URL的应用程序,由该应用调用短URL生成器生成短URL,并将该短URL展示给用户,用户在浏览器中点击该短URL时,请求发送到短URL生成器(短URL生成器以HTTP服务器的方式对外提供服务,短URL域名指向短URL生成器),短URL生成器返回HTTP重定向响应,将用户请求重定向到最初的原始长URL,浏览器访问长URL服务器,完成请求服务。

又是一个显而易见,短URL和长URL之间必须存在一一匹配的映射关系,只有在满足这种关系后,点击短URL才能跳转到想要的长URL。存储这种映射关系的数据结构就是键值对HashMap。

总结一下,短链的优势:

  1. 减少文本长度,常用于发布微博或Twitter(有字数限制),短信群发(减少短信发送成本)等场景
  2. 可阅读性:相比于长链接里一大堆不知所以的参数,短链接更加简洁友好
  3. 安全:不暴露访问参数。当然短链接转换为长链接后,小部分用户(开发者)还是能分析出参数的
  4. 长链接在有些平台上无法自动识别为超链接
  5. URL与二维码。长链接在生成二维码时更密集一些;短链接在生成二维码时更稀疏。一般而言,越稀疏的二维码,识别扫描效率更高,尤其是在光线不好、二维码部分遮挡或图像质量较差的情况下。

Hash算法

将一个原始的长URL经过某种计算生成对应的,唯一的短URL的过程就是Hash算法。所谓唯一,指的是长URL1和长URL2经过Hash计算后不会生成相同的短URL。因此短URL服务的核心之一是一款效率高(计算速度快)和冲突概率低(不冲突最好,但不太实际)的算法。

MurmurHash就是这样一种算法,Redis,Google Guava,Apache commons-codec内部都有这种算法的实现。

public class HashUtil {private static final int c1 = 0xcc9e2d51;private static final int c2 = 0x1b873593;private static final int r1 = 15;private static final int r2 = 13;private static final int m = 5;private static final int n = 0xe6546b64;private static final int DEFAULT_SEED = 0;/*** TODO:直接搬自Google Guava的MurmurHash 32bits生成算法(还有64位,128位)*/public static int hash32(String str) {return hash32(str.getBytes());}private static int hash32(byte[] key) {int hash = HashUtil.DEFAULT_SEED;final int len = key.length;int i = 0;int k = 0;for (; i + 4 <= len; i += 4) {k = ((key[i + 3] & 0xff) << 24)| ((key[i + 2] & 0xff) << 16)| ((key[i + 1] & 0xff) << 8)| (key[i] & 0xff);k *= c1;k = Integer.rotateLeft(k, r1);k *= c2;hash ^= k;hash = Integer.rotateLeft(hash, r2);hash = hash * m + n;}int k1 = 0;switch (len - i) {case 3:k1 = (key[i + 2] & 0xff) << 16;case 2:k1 |= (key[i + 1] & 0xff) << 8;case 1:k1 |= key[i] & 0xff;k1 *= c1;k1 = Integer.rotateLeft(k1, r1);k1 *= c2;hash ^= k1;}hash ^= len;hash ^= hash >>> 16;hash *= 0x85ebca6b;hash ^= hash >>> 13;hash *= 0xc2b2ae35;hash ^= hash >>> 16;return hash;}/*** 转换为62进制字符串, 即包含a-z, A-Z, 0-9共62个字符*/private static String to62Hex(int num) {num = Math.abs(num);String chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";StringBuilder sb = new StringBuilder();int remainder;while (num > 62 - 1) {remainder = Long.valueOf(num % 62).intValue();sb.append(chars.charAt(remainder));num = num / 62;}sb.append(chars.charAt(Long.valueOf(num).intValue()));return sb.reverse().toString();}public static void main(String[] args) {int i = hash32("https://google.com/");String s = to62Hex(i);// 输出:1027772095 17yqthSystem.out.println(i + " " + s);}
}

https://google.com/经过hash32方法计算后的结果为1027772095,这是一串十进制的整型值,再经过to62Hex方法转化为62进制字符串得到17yqth。

Hash冲突

Hash冲突是无法避免的,但在业务上一定不能有多个长URL映射为同一个短URL的情况存在。

为了防止数据库中出现相同短链,用刚生成的短链作为查询条件去数据库中查询看是否有相同的短链,如果有则需要比对这个短链对应的长链与正在处理的长链地址是否一样。如果一样,说明传入的长链是重复的,则此短链可直接复用,不用再存储一次。

如果不一样,则说明发生冲突,此时可以给长链加一串特殊的字符,然后再进行Hash运算,如果此次不冲突则可以将长链和这个特殊字符拼接起来和短链一并存储到数据库中下次接受到短链请求后,把特殊字符截取掉,然后再进行重定向。

判断优化

长URL和短URL的映射关系是存储于数据库中,判断是否发生Hash冲突时需要查询数据库,这样数据库或许会成为性能评价。

很自然想到引入分布式缓存集群。此外还有布隆过滤器。

服务设计

一道频繁出现的面试题:如何设计一个十亿级、高性能、高可用的短URL服务?

需求分析:

  1. 使用几位随机字符
  2. 是否需要考虑URL的过期时间,即经过多长时间后,URL不能转换为对应的长URL
  3. 是否需要考虑URL(及对应的营销文案)的点击率
  4. 是否需要考虑支持用户自定义短URL?即是否支持用户自定义(调用方或客户端)短URL。用户可以指定一个长URL对应的短URL内容,只要这个短URL还没有被使用

字符个数

使用62进制字符串,1个字符可以表示62种结果,2个字符可以表示62*62=3844种结果。以此类推,5个字符可以表示916132832种结果,约9亿,即可以代表9亿种不同的长URL,理论上并且在实际上足够使用。目前应该没有哪家公司有这么大的实际需求量,并且短URL是可以回收的(技术可行性上)。

在做架构设计时,架构师们总是习惯于冗余设计;5个字符和6个字符,几乎没有什么技术上的区别。鉴于面试官的题目是十亿级别的短URL服务,因此5个字符不够用。6个字符可以表示56800235584种结果,约568亿个不同的URL。

所以,我们看到的短URL一般都是6个62位二进制字符。

分库分表

如果使用MySQL这类关系型数据库存储,则需要考虑分库分表。如果使用非关系型数据库,如HBase,也需要做集群化部署保证数据库系统高可用。

短URL有效期

数据库存储长、短URL映射关系时,除了这两个核心字段,还可以考虑增加最后访问时间字段,短URL被访问时,则更新此字段。然后可考虑以一个月为执行频率,在凌晨短URL服务集群负载低时,发起定时调度任务,分批查询数据库节点,扫描获取最近1年(或2年)没有被访问(最后访问时间是1/2年前)的短URL,做逻辑删除,回收利用。

短链跳转

如果需要对营销活动进行数据分析,则需要做页面埋点,页面埋点肯定只能对长链接进行埋点,因为长链接里URL携带有各种参数。

浏览器请求短URL,短URL到达短链服务器,短链服务器返回长URL后,浏览器访问长URL的动作叫重定向,重定向有301和302两类。

如果要做页面埋点,做数据分析,做营销活动效果可视化等一系列任务,则推荐使用302这种方式。

301和302的区别:

  • 301:代表永久重定向,也就是说第一次请求拿到长链接后,下次浏览器再去请求短链的话,不会向短网址服务器请求,而是直接从浏览器的缓存里拿,这样在server层面就无法获取到短网址的点击数,如果这个链接刚好是某个活动的链接,也就无法分析此活动的效果。
  • 302:代表临时重定向,也就是说每次去请求短链都会去请求短网址服务器(除非响应头中有Cache-Control或Expired指示使用浏览器缓存),这样就便于server统计点击数,用302会给server增加一点压力,但在数据异常重要的今天,这点统计代码和性能损失是值得的。

短URL生成方式

长URL通过某种函数,计算得到一个6个字符的短URL。

Hash

将长URL利用MD5或SHA256等单项散列算法,进行Hash计算,得到128bit或256bit的Hash值。然后对该Hash值进行Base64编码,得到22个或43个Base64字符,再截取前面的6个字符,就得到短URL。
在这里插入图片描述
但是这样得到的短URL,可能会发生Hash冲突(MD5或SHA256计算得到的Hash值几乎不会冲突,但Base64编码后再截断的6个字符有可能会冲突)。所以在生成时,需要先校验该短URL是否已经映射为其他的长URL,如果是,那么需要重新计算(换单向散列算法,或者换Base64编码截断位置)。重新计算得到的短URL依然可能冲突,需要再重新计算。但是这样的冲突处理需要多次到存储中查找 URL,性能损耗比较严重。

自增长

一种免冲突的算法是用自增长自然数来实现,即维持一个自增长的二进制自然数,然后将该自然数进行Base64编码即可得到一系列的短URL。这样生成的的短URL必然唯一,而且还可以生成小于6个字符的短URL,如自然数0的Base64编码是字符A,则用https://1.cn/A作为短URL。

但这种算法将导致短URL是可猜测的,如果某个应用在某个时间段内生成一批短URL,则这批短URL就会集中在一个自然数区间内。只要知道了其中一个短URL,就可以通过自增(以及自减)的方式请求访问其他URL。不允许短URL可预测。

预生成

预先生成一批没有冲突的短URL字符串,当外部请求输入长URL需要生成短URL时,直接从预先生成好的短URL字符串池中获取一个即可。

采用随机数来实现,6个字符每个字符都用随机数产生(用0~63的随机数产生一个Base64编码字符)。为了避免随机数产生的短URL冲突,需要在预生成的时候检查该URL是否已经存在(采用布隆过滤器检查)。因为预生成短URL是离线的,所以这时不会有性能方面的问题。

架构

一个可供参考的架构如下图所示:
在这里插入图片描述
短URL预加载服务器此前已经从短URL预生成文件服务器(HDFS)中加载一批短URL存放在自己的内存中,这时只需要从内存中返回一个短URL即可,同时将短URL与长URL的映射关系存储在HBase数据库中,时序图如下图所示:
在这里插入图片描述
对于用户通过客户端请求访问短URL的过程(即输入短URL,请求返回长URL),请求通过负载均衡服务器发送到短URL服务器集群,短URL服务器首先到缓存服务器中查找是否有该短URL,如果有,立即返回对应的长URL,短URL生成服务器构造重定向响应返回给客户端应用。

如果缓存没有用户请求访问的短URL,短URL服务器将访问HBase短URL数据库服务器集群。如果数据库中存在该短URL,短URL服务器会将该短URL写入缓存服务器集群,并构造重定向响应返回给客户端应用。若HBase中没有该短URL,短URL服务器将构造404响应返回给客户端应用,时序图如下图所示:
在这里插入图片描述
回到需求分析部分:

  • 为了保证系统高可用,上面的架构图里的应用服务器、文件服务器、数据库服务器都采用集群部署方案
  • 为了满足高性能要求,引入Redis缓存集群。80%以上的访问请求将被设计为通过缓存返回

标准Base64编码表

在这里插入图片描述
其中+/在URL中会被编码为%2B以及%2F,而%在写入数据库时又和SQL编码规则冲突,需要进行再编码,因此直接使用标准Base64编码进行短URL编码并不合适。URL 保留字符编码表如下
在这里插入图片描述
所以需要针对URL场景对Base64编码进行改造,使用URL保留字符表以外的字符对Base64编码表中的62,63进行改造:将+改为-,将/改为_

参考

  • 高性能短链设计

相关文章:

短URL服务设计

引言 在营销系统里&#xff0c;为了增加系统的活跃用户数&#xff0c;经常会有各种各样的营销活动。这类活动几乎都是为了充分利用存量用户的价值&#xff0c;促使他们分享产品或App以达到触达到更多用户的目的。又或者是出于营销目的&#xff0c;群发优惠券触达短信这种场景。…...

Kafka集成flume

1.flume作为生产者集成Kafka kafka作为flume的sink&#xff0c;扮演消费者角色 1.1 flume配置文件 vim $kafka/jobs/flume-kafka.conf # agent a1.sources r1 a1.sinks k1 a1.channels c1 c2# Describe/configure the source a1.sources.r1.type TAILDIR #记录最后监控文件…...

如何让视频有高级感 高级感视频制作方法 高级感视频怎么剪 会声会影视频剪辑制作教程 会声会影中文免费下载

高质量视频通常具有清晰的画面、优质的音频和令人印象深刻的视觉效果。这篇文章来了解如何让视频有高级感&#xff0c;高级感视频制作方法。 一、如何让视频有高级感 要让视频有高级感&#xff0c;要注意以下几个要点&#xff1a; 1、剧本和故事性&#xff1a;一个好的剧本和…...

详解|访问学者申请被拒原因有哪些?

访问学者项目为全球科研人员提供了一个难得的机会&#xff0c;让他们能够跨越国界&#xff0c;深入不同的学术环境&#xff0c;进行学术交流和合作。然而&#xff0c;并非所有申请者都能如愿以偿地获得这一机会。本文将对访问学者申请中常见的被拒原因进行详细解析&#xff0c;…...

[鹤城杯 2021]BabyRSA

题目&#xff1a; from Crypto.Util.number import getPrime, bytes_to_long from secret import flagp getPrime(1024) q getPrime(1024) n p * q e 65537 hint1 p >> 724 hint2 q % (2 ** 265) ct pow(bytes_to_long(flag), e, n) print(hint1) print(hint2) p…...

西安市工业倍增引导基金子基金申报条件流程和材料程序指南(2024年)

一、基本情况 产业投资基金是以产业发展为首要目标&#xff0c;围绕经济社会发展规划和产业发展政策&#xff0c;发挥“有效市场”作用&#xff0c;支持重点领域、重点产业、重点区域&#xff08;如&#xff1a;全市六大支柱产业、五大新兴产业领域成熟期重点规模以上企业以及“…...

微型丝杆的耐用性和延长使用寿命的关键因素!

无论是机械设备&#xff0c;还是精密传动元件&#xff0c;高精度微型丝杆是各种机械设备中不可或缺的重要组件。它的精度和耐用性直接影响着工作效率和产品品质&#xff0c;在工业技术不断进步的情况下&#xff0c;对微型丝杆的性能要求也越来越高&#xff0c;如何提升微型丝杆…...

音频文件下载后,如何轻松转换格式?

在我们日常的数字生活中&#xff0c;下载各种音频文件是司空见惯的事情。然而&#xff0c;有时候我们可能需要将这些音频文件转换为不同的格式&#xff0c;以适应不同的设备或编辑需求。无论您是希望将下载的音频文件转换为通用的MP3格式&#xff0c;还是需要将其转换为高保真的…...

Intel平台,13600KF+3060Ti,虚拟机安装macOS 14(2024年6月)

距离上次装macOS虚拟机已经有一段时间了&#xff0c;macOS系统现在大版本升级的速度也是越来越快了&#xff0c;由于Office只支持最新三个版本的macOS&#xff0c;所以现在保底也得安装macOS 12了&#xff0c;我这次是用macOS 14做实验&#xff0c;13和12的安装方式和macOS 14一…...

Cookie、Session、Token的关系和区别

关系 Session与Cookie&#xff1a;Session通常依赖于Cookie来工作。当服务器为客户端创建一个Session时&#xff0c;它会在服务器上存储与客户端相关的信息&#xff0c;并将一个唯一的SessionID通过Cookie发送给客户端。客户端在后续的请求中会携带这个Cookie&#xff08;包含…...

Windows 11 中安装 Docker Desktop 并安装镜像

本该主要介绍在 Windows 11 中安装 Docker Desktop 时的一些准备工作&#xff0c;以及该如何下载和安装&#xff0c;然后分别使用管理界面和 Docker 命令安装两个镜像。 一、准备工作 在 Windows 11 中安装 Docker Desktop 前&#xff0c;需要做一些准备。打开 【Windows 功能…...

深入剖析Java线程池之“newWorkStealingPool“

1. 概述 newWorkStealingPool 是Java 8中引入的一个新型线程池,它基于ForkJoinPool实现,并采用了“工作窃取”(Work-Stealing)算法。这种线程池特别适用于可并行化且计算密集型的任务,能够充分利用多核CPU资源,提高任务执行效率。 2. 工作窃取算法(Work-Stealing Algor…...

《跟我一起学“网络安全”》——安全设备

安全设备 一、安全设备–IDS IDS入侵检测 (1)什么是入侵检测&#xff1a; 入侵检测系统&#xff08;intrusion detection system&#xff0c;简称“IDS”&#xff09;是一种对网络传输进行即时监视&#xff0c;在发现可疑传输时发出警报或者采取主动反应措施的网络安全设备。…...

猜测Tomcat如何实现WebSocket协议

一、WebSocket协议的实现 (一)WebSocket是官方的协议接口标准。 (二)如果一门编程语言可以网络连接和并发&#xff0c;就能创建一种WebSocket实现。 (三)同一种编程语言&#xff0c;有不同的协议实现版本和框架。 二、Tomcat实现 在Tomcat容器中实现了对应的WebSocket版本&am…...

uniApp @input事件更改输入框值,值改变了但是页面没更新新的值

<uni-easyinputtype"text"trim"all":inputBorder"false"v-model"customFormData.completePercent"input"(val) > completeOnInput(val)"placeholder"请输入" /> function completeOnInput(val) {let num…...

两行css 实现瀑布流

html <ul ><li><a href"" ><img src"05094532gc6w.jpg" alt"111" /><p>传奇</p></a></li><li><a href"" ><img src"05094532gc6w.jpg" alt"111"…...

Centos7.9部署单节点K8S环境

Centos7.9部署单节点K8S环境 通过Centos extras镜像源安装K8S环境&#xff0c;优点是方便快捷&#xff0c;缺点是版本较低&#xff0c;安装后的版本为1.5.2。 1. 准备工作 关闭selinux [rootlocalhost ~]# cat /etc/selinux/config# This file controls the state of SELin…...

【CV】stable diffusion初步理解

来自gpt-4o Stable diffusion 和DALLE的关系 Stable Diffusion 和 DALL-E 都是生成图像的人工智能模型&#xff0c;但它们有不同的开发背景和技术实现。 Stable Diffusion: 开发者: 由Stability AI开发&#xff0c;并与CompVis和LAION等组织合作。技术: 基于扩散模型&#xf…...

足底筋膜炎最好的恢复办法

足底筋膜炎是一种由足底筋膜受到炎症刺激而引起的疼痛和不适的疾病。其典型症状主要包括&#xff1a; 1、足底疼痛&#xff1a;这是足底筋膜炎最常见的症状。疼痛通常位于足跟部位&#xff0c;患者可能感到刺痛或灼热感。尤其在早晨起床或长时间站立后&#xff0c;这种疼痛感会…...

Fiddler抓包工具介绍

下载 下载:Web Debugging Proxy and Troubleshooting Tools|Fiddler 进去要填一个表 汉化版 百度网盘 请输入提取码 提取码&#xff1a;xq9t 下载过附件之后分别把两个文件 点开fiddler就ok了 配置https fiddler要想抓到https包(解密的),点击tools->options勾选三个对…...

知乎号开始运营了,宣传一波

知乎号开始发布一些小说、散文还有诗歌了&#xff0c;欢迎大家多来关注 知乎链接&#xff1a;姜亚轲 每篇小说都改编成网易云音乐&#xff0c;文章中也有链接&#xff0c;我做的词&#xff0c;Suno编曲和演唱&#xff0c;欢迎大家来听听...

Go 基础丨切片 slice

1. 底层 runtime/slice.go type slice struct {array unsafe.Pointer // 指向底层数组len int // 切片元素数量cap int // 底层数组容量 }reflect/value.go type SliceHeader struct {Data uintptrLen intCap int }2. 创建 根据数组创建 s : arr[0:3]字面…...

哪个牌子充电宝好用?精选四大热门款充电宝品牌!公认好用

在当今快节奏的生活中&#xff0c;充电宝已经成为了我们日常生活中不可或缺的数码伴侣。无论是旅行、出差还是日常通勤&#xff0c;拥有一款好用的充电宝&#xff0c;能够确保我们的手机、平板等设备随时保持充足电量。然而&#xff0c;市场上充电宝品牌繁多&#xff0c;如何选…...

WPF/C#:如何将数据分组显示

WPF Samples中的示例 在WPF Samples中有一个关于Grouping的Demo。 该Demo结构如下&#xff1a; MainWindow.xaml如下&#xff1a; <Window x:Class"Grouping.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x&q…...

leetcode 200 岛屿数量

思路 就是深搜&#xff0c;将可以走到的都标为0 ##代码 class Solution {static int[][] to {{1,0},{0,1},{-1,0},{0,-1}};public int numIslands(char[][] grid) {// 深搜int result 0;for (int i 0; i < grid.length; i) {for (int j 0; j < grid[0].length; j)…...

​1:25万基础电子地图(江西版)

我们在《50幅1:25万基础电子地图&#xff08;四川版&#xff09;》和《1&#xff1a;25基础电子地图&#xff08;云南版&#xff09;》等文中&#xff0c;为你分享过四川和云南的基础电子地图。 现在我们再为你分享江西的1&#xff1a;25万基础电子地图&#xff0c;你可以在文…...

【RabbitMQ】初识 RabbitMQ

初识 RabbitMQ 1.认识 RabbitMQ1.1 介绍1. 2.使用场景1.2.1 推送通知1.2.2 异步任务1.2.3 多平台应用的通信1.2.4 消息延迟1.2.5 远程过程调用 1.3 特性 2.基本概念2.1 生产者、消费者和代理2.2 消息队列2.3 交换机2.3.1 direct2.3.2 topic2.3.3 headers2.3.4 fanout 2.4 绑定2…...

Qt QListView自定义树状导航控件

大部分的软件都有多个页面&#xff0c;这时候就需要一个导航栏控件&#xff0c;通过在导航栏中选择某一栏&#xff0c;同时显示对应的页面。 本文代码效果如下&#xff1a; 本文的导航栏控件基于大佬 feiyangqingyun 的导航栏控件博客Qt/C编写自定义控件46-树状导航栏_qt之实现…...

Java 数组的全面解析与应用

Java 中的数组是一种基础且重要的数据结构&#xff0c;用于存储相同类型的多个数据项。它提供了有效的数据组织和访问机制&#xff0c;是 Java 编程中不可或缺的部分。本文将从多个角度全面探讨 Java 数组的特性、操作和实际应用&#xff0c;帮助读者深入理解和有效利用这一数据…...

Thinkphp起名网宝宝起名网站源码

Thinkphp起名网宝宝起名网站源码 源码介绍 1.宝宝在线起名 2.八字起名&#xff0c;周易取名 3.一对一起名 5.支持手机wap 链接数据库地址&#xff1a;Application\Common\Conf 修改里面config.php数据库连接&#xff0c;导入sm.sql数据库文件即可 伪静态用thinkphp 后台…...

集团网站建设调研报告/长沙网络推广平台

参考&#xff1a;Tiny Spring 分析一&#xff0c;原文&#xff1a;1000行代码读懂Spring&#xff08;一&#xff09;- 实现一个基本的IoC容器 代码地址&#xff1a;https://github.com/xiaoxicode/jdk_source_1.7/tree/master/tinyspring 特此声明,本文不能算严格意义上的原创…...

英文搜索网站/app拉新项目推广代理

一、下载consul 地址&#xff1a;https://www.consul.io/downloads.html 二、解压到目录&#xff1a;C:\Tool\Consul (可任意目录) 三、在path中添加环境变量&#xff1a; 四、测试>在cmd中输入:consul 结果如下图便说明成功 五、启动&#xff1a;consul agent -dev -u…...

买完域名怎么创建网站/海外网站cdn加速

问题 电脑在安装较新版本的格式工厂&#xff08;例如V5.12&#xff09;后&#xff0c;会自启Bright Data服务&#xff0c;并最小化到任务栏图标中。该服务是一个数据上传和下载工具&#xff0c;开启该服务可以获取格式工厂的白金功能&#xff0c;其协议说明如下图所示&#xf…...

网站建设资讯/推广平台都有哪些

一个Project 引用 另外 一个Project 显示黄色叹号&#xff0c;后来发现 后一本Project的build设定为.Net4.5, 前一个为4.0, 将版本改为一致后&#xff0c;问题解决。转载于:https://www.cnblogs.com/fdyang/p/4270041.html...

怎样做才能让百度搜到网站产品/沈阳网页建站模板

来源于知乎&#xff1a;https://www.zhihu.com/question/25532384/answer/411179772 进程是资源分配的最小单位&#xff0c;线程是CPU调度的最小单位。这样的回答感觉太抽象&#xff0c;都不太容易让人理解。 做个简单的比喻&#xff1a;火车和车厢 1.进程火车&#xff0c; 线…...

双线主机可以做彩票网站吗/网站优化包括对什么优化

64位windows安装storm前需要先搞定zookeeper和python&#xff0c;所以下面我们3步走&#xff1a; 一、zookeeper 1、上https://zookeeper.apache.org/点击下方download到新页面&#xff0c;还得点一次中间的download&#xff0c;再选一个镜像链接http://mirrors.tuna.tsinghua.…...