Redis【入門】就這一篇!

来源:https://www.cnblogs.com/wmyskxz/archive/2018/05/31/9114729.html
-Advertisement-
Play Games

Redis 概述 在我們日常的Java Web開發中,無不都是使用資料庫來進行數據的存儲,由於一般的系統任務中通常不會存在高併發的情況,所以這樣看起來並沒有什麼問題,可是一旦涉及大數據量的需求,比如一些商品搶購的情景,或者是主頁訪問量瞬間較大的時候,單一使用資料庫來保存數據的系統會因為面向磁碟,磁碟 ...


Redis 概述

在我們日常的Java Web開發中,無不都是使用資料庫來進行數據的存儲,由於一般的系統任務中通常不會存在高併發的情況,所以這樣看起來並沒有什麼問題,可是一旦涉及大數據量的需求,比如一些商品搶購的情景,或者是主頁訪問量瞬間較大的時候,單一使用資料庫來保存數據的系統會因為面向磁碟,磁碟讀/寫速度比較慢的問題而存在嚴重的性能弊端,一瞬間成千上萬的請求到來,需要系統在極短的時間內完成成千上萬次的讀/寫操作,這個時候往往不是資料庫能夠承受的,極其容易造成資料庫系統癱瘓,最終導致服務宕機的嚴重生產問題。

NoSQL 技術

為了剋服上述的問題,Java Web項目通常會引入NoSQL技術,這是一種基於記憶體的資料庫,並且提供一定的持久化功能。

RedisMongoDB是當前使用最廣泛的NoSQL,而就Redis技術而言,它的性能十分優越,可以支持每秒十幾萬此的讀/寫操作,其性能遠超資料庫,並且還支持集群、分散式、主從同步等配置,原則上可以無限擴展,讓更多的數據存儲在記憶體中,更讓人欣慰的是它還支持一定的事務能力,這保證了高併發的場景下數據的安全和一致性。

Redis 在 Java Web 中的應用

Redis 在 Java Web 主要有兩個應用場景:

  • 存儲 緩存 用的數據;
  • 需要高速讀/寫的場合使用它快速讀/寫

緩存

在日常對資料庫的訪問中,讀操作的次數遠超寫操作,比例大概在 1:93:7,所以需要讀的可能性是比寫的可能大得多的。當我們使用SQL語句去資料庫進行讀寫操作時,資料庫就會去磁碟把對應的數據索引取回來,這是一個相對較慢的過程。

如果我們把數據放在 Redis 中,也就是直接放在記憶體之中,讓服務端直接去讀取記憶體中的數據,那麼這樣速度明顯就會快上不少,並且會極大減小資料庫的壓力,但是使用記憶體進行數據存儲開銷也是比較大的,限於成本的原因,一般我們只是使用 Redis 存儲一些常用和主要的數據,比如用戶登錄的信息等。

一般而言在使用 Redis 進行存儲的時候,我們需要從以下幾個方面來考慮:

  • 業務數據常用嗎?命中率如何?如果命中率很低,就沒有必要寫入緩存;
  • 該業務數據是讀操作多,還是寫操作多?如果寫操作多,頻繁需要寫入資料庫,也沒有必要使用緩存;
  • 業務數據大小如何?如果要存儲幾百兆位元組的文件,會給緩存帶來很大的壓力,這樣也沒有必要;

在考慮了這些問題之後,如果覺得有必要使用緩存,那麼就使用它!使用 Redis 作為緩存的讀取邏輯如下圖所示:

從上圖我們可以知道以下兩點:

  1. 第一次讀取數據的時候,讀取 Redis 的數據就會失敗,此時就會觸發程式讀取資料庫,把數據讀取出來,並且寫入 Redis 中;
  2. 第二次以及以後需要讀取數據時,就會直接讀取 Redis,讀到數據後就結束了流程,這樣速度就大大提高了。

從上面的分析可以知道,讀操作的可能性是遠大於寫操作的,所以使用 Redis 來處理日常中需要經常讀取的數據,速度提升是顯而易見的,同時也降低了對資料庫的依賴,使得資料庫的壓力大大減少。

分析了讀操作的邏輯,下麵我們來看看寫操作的流程

從流程可以看出,更新或者寫入的操作,需要多個 Redis 的操作,如果業務數據寫次數遠大於讀次數那麼就沒有必要使用 Redis。

關於使用記憶體存儲數據,我知道谷歌好像就是把所有互聯網的數據都存儲在記憶體條的,所以才會有如此高質量、高效的搜索,但它畢竟是谷歌...

高速讀/寫的場合

在如今的互聯網中,越來越多的存在高併發的情況,比如天貓雙11、搶紅包、搶演唱會門票等,這些場合都是在某一個瞬間或者是某一個短暫的時刻有成千上萬的請求到達伺服器,如果單純的使用資料庫來進行處理,就算不崩,也會很慢的,輕則造成用戶體驗極差用戶量流失重則資料庫癱瘓,服務宕機,而這樣的場合都是不允許的!

所以我們需要使用 Redis 來應對這樣的高併發需求的場合,我們先來看看一次請求操作的流程圖

我們來進一步闡述這個過程:

  1. 當一個請求到達伺服器時,只是把業務數據在 Redis 上進行讀寫,而沒有對資料庫進行任何的操作,這樣就能大大提高讀寫的速度,從而滿足高速響應的需求
  2. 但是這些緩存的數據仍然需要持久化,也就是存入資料庫之中,所以在一個請求操作完 Redis 的讀/寫之後,會去判斷該高速讀/寫的業務是否結束,這個判斷通常會在秒殺商品為0,紅包金額為0時成立,如果不成立,則不會操作資料庫;如果成立,則觸發事件將 Redis 的緩存的數據以批量的形式一次性寫入資料庫,從而完成持久化的工作。

Redis 的安裝

訪問地址:https://github.com/ServiceStack/redis-windows/tree/master/downloads

把 Redis 下載下來後找到一個合適的地方解壓,就能得到如下圖所示的目錄(這裡空格被替換成了%20...):

為了方便啟動,我們在該目錄下新建一個 startup.cmd 的文件,然後將以下內容寫入文件:

redis-server redis.windows.conf

這個命令其實就是在調用 redis-server.exe 命令來讀取 redis.window.conf 的內容,我們雙擊剛纔創建好的 startup.cmd 文件,就能成功的看到 Redis 啟動:

上圖的提示信息告訴了我們:① Redis 當前的版本為 3.0.503;② Redis 運行在 6379 埠;③ Redis 進程的 PID 為 14748;④ 64 位。

我們可以打開同一個文件夾下的 redis-cli.exe 文件,這是 Redis 自帶的一個客戶端工具,它可以用來連接到我們當前的 Redis 伺服器,我們做以下測試:

如此,我們便在 Windows 的環境下安裝好了 Redis。


在 Java 中使用 Redis

第一步:添加 Jedis 依賴

想要在 Java 中使用 Redis 緩存,需要添加相關的Jar包依賴,打開Maven倉庫的網站:https://mvnrepository.com/ ,搜索Jedis:

把它導入工程中去就可以啦,下麵我們來對Redis的寫入性能做一下測試:

@Test
public void redisTester() {
    Jedis jedis = new Jedis("localhost", 6379, 100000);
    int i = 0;
    try {
        long start = System.currentTimeMillis();// 開始毫秒數
        while (true) {
            long end = System.currentTimeMillis();
            if (end - start >= 1000) {// 當大於等於1000毫秒(相當於1秒)時,結束操作
                break;
            }
            i++;
            jedis.set("test" + i, i + "");
        }
    } finally {// 關閉連接
        jedis.close();
    }
    // 列印1秒內對Redis的操作次數
    System.out.println("redis每秒操作:" + i + "次");
}
-----------測試結果-----------
redis每秒操作:10734

據說 Redis 的性能能達到十萬級別,我不敢相信我的台式機電腦只有十分之一不到的性能,雖然說這裡不是流水線的操作,會造成一定的影響,但我還是不信邪,我查到了官方的性能測試方法:

首先在Redis根目錄下召喚Cmd:具體方法是按住【Shift】點擊右鍵

然後輸入命令:【redis-benchmark -n 100000 -q】:來同時執行10萬個請求測試性能

好吧,我同時在我的筆記本上測試了一下,結果更加慘淡...low啊low...

第二步:使用 Redis 連接池

跟資料庫連接池相同,Java Redis也同樣提供了類redis.clients.jedis.JedisPool來管理我們的Reids連接池對象,並且我們可以使用redis.clients.jedis.JedisPoolConfig來對連接池進行配置,代碼如下:

JedisPoolConfig poolConfig = new JedisPoolConfig();
// 最大空閑數
poolConfig.setMaxIdle(50);
// 最大連接數
poolConfig.setMaxTotal(100);
// 最大等待毫秒數
poolConfig.setMaxWaitMillis(20000);
// 使用配置創建連接池
JedisPool pool = new JedisPool(poolConfig, "localhost");
// 從連接池中獲取單個連接
Jedis jedis = pool.getResource();
// 如果需要密碼
//jedis.auth("password");

Redis 只能支持六種數據類型(string/hash/list/set/zset/hyperloglog)的操作,但在 Java 中我們卻通常以類對象為主,所以在需要 Redis 存儲的五中數據類型與 Java 對象之間進行轉換,如果自己編寫一些工具類,比如一個角色對象的轉換,還是比較容易的,但是涉及到許多對象的時候,這其中無論工作量還是工作難度都是很大的,所以總體來說,就操作對象而言,使用 Redis 還是挺難的,好在 Spring 對這些進行了封裝和支持。

第三步:在 Spring 中使用 Redis

上面說到了 Redis 無法操作對象的問題,無法在那些基礎類型和 Java 對象之間方便的轉換,但是在 Spring 中,這些問題都可以通過使用RedisTemplate得到解決!

想要達到這樣的效果,除了 Jedis 包以外還需要在 Spring 引入 spring-data-redis 包:https://mvnrepository.com/artifact/org.springframework.data/spring-data-redis

這裡把2.0.7最新版本標紅的意思是:別老想著使用最新的Jar包,特別是涉及到框架的一些東西,筆者用實際的操作體驗告訴你們,引入該版本的包是會導致Jar包衝突的(也就是莫名其妙的錯誤),我乖乖換回了1.7.2的版本,代碼就通了...我們來看看怎麼做吧:

(1)第一步:使用Spring配置JedisPoolConfig對象

大部分的情況下,我們還是會用到連接池的,於是先用 Spring 配置一個 JedisPoolConfig 對象:

<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
    <!--最大空閑數-->
    <property name="maxIdle" value="50"/>
    <!--最大連接數-->
    <property name="maxTotal" value="100"/>
    <!--最大等待時間-->
    <property name="maxWaitMillis" value="20000"/>
</bean>

(2)第二步:為連接池配置工廠模型

好了,我們現在配置好了連接池的相關屬性,那麼具體使用哪種工廠實現呢?在Spring Data Redis中有四種可供我們選擇的工廠模型,它們分別是:

  • JredisConnectionFactory
  • JedisConnectionFactory
  • LettuceConnectionFactory
  • SrpConnectionFactory

我們這裡就簡單配置成JedisConnectionFactory:

<bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
    <!--Redis服務地址-->
    <property name="hostName" value="localhost"/>
    <!--埠號-->
    <property name="port" value="6379"/>
    <!--如果有密碼則需要配置密碼-->
    <!--<property name="password" value="password"/>-->
    <!--連接池配置-->
    <property name="poolConfig" ref="poolConfig"/>
</bean>

(3)第三步:配置RedisTemplate

普通的連接根本沒有辦法直接將對象直接存入 Redis 記憶體中,我們需要替代的方案:將對象序列化(可以簡單的理解為繼承Serializable介面)。我們可以把對象序列化之後存入Redis緩存中,然後在取出的時候又通過轉換器,將序列化之後的對象反序列化回對象,這樣就完成了我們的要求:

RedisTemplate可以幫助我們完成這份工作,它會找到對應的序列化器去轉換Redis的鍵值:

<bean id="redisTemplate"
      class="org.springframework.data.redis.core.RedisTemplate"
      p:connection-factory-ref="connectionFactory"/>

筆者從《JavaEE互聯網輕量級框架整合開發》中瞭解到,這一步需要配置單獨的序列化器去支撐這一步的工作,但是自己在測試當中,發現只要我們的POJO類實現了Serializable介面,就不會出現問題...所以我直接省略掉了配置序列化器這一步...

(4)第四步:編寫測試

首先編寫好支持我們測試的POJO類:

/**
 * @author: @我沒有三顆心臟
 * @create: 2018-05-30-下午 22:31
 */
public class Student implements Serializable{

    private String name;
    private int age;

    /**
     * 給該類一個服務類用於測試
     */
    public void service() {
        System.out.println("學生名字為:" + name);
        System.out.println("學生年齡為:" + age);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

然後編寫測試類:

@Test
public void test() {
    ApplicationContext context =
            new ClassPathXmlApplicationContext("applicationContext.xml");
    RedisTemplate redisTemplate = context.getBean(RedisTemplate.class);
    Student student = new Student();
    student.setName("我沒有三顆心臟");
    student.setAge(21);
    redisTemplate.opsForValue().set("student_1", student);
    Student student1 = (Student) redisTemplate.opsForValue().get("student_1");
    student1.service();
}

運行可以成功看到結果:

第四步:在 SpringBoot 中使用 Redis

(1)在SpringBoot中添加Redis依賴:

<!-- Radis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

(2)添加配置文件:

在SpringBoot中使用.properties或者.yml都可以,這裡給出.properties的例子,因為自己的.yml文件看上去感覺亂糟糟的:

# REDIS (RedisProperties)
# Redis資料庫索引(預設為0)
spring.redis.database=0
# Redis伺服器地址
spring.redis.host=localhost
# Redis伺服器連接埠
spring.redis.port=6379
# Redis伺服器連接密碼(預設為空)
spring.redis.password=
# 連接池最大連接數(使用負值表示沒有限制)
spring.redis.pool.max-active=8
# 連接池最大阻塞等待時間(使用負值表示沒有限制)
spring.redis.pool.max-wait=-1
# 連接池中的最大空閑連接
spring.redis.pool.max-idle=8
# 連接池中的最小空閑連接
spring.redis.pool.min-idle=0
# 連接超時時間(毫秒)
spring.redis.timeout=0

(3)測試訪問:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest()
public class ApplicationTests {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Test
    public void test() throws Exception {

        // 保存字元串
        stringRedisTemplate.opsForValue().set("aaa", "111");
        Assert.assertEquals("111", stringRedisTemplate.opsForValue().get("aaa"));

    }
}

通過上面這段極為簡單的測試案例演示瞭如何通過自動配置的StringRedisTemplate對象進行Redis的讀寫操作,該對象從命名中就可註意到支持的是String類型。原本是RedisTemplate

運行測試,如果一切成功則不會報錯,如果我們沒有拿到或者拿到的數不是我們想要的 “111” ,那麼則會報錯,這是使用Assert的好處(下麵是我改成112之後運行報錯的結果):

(4)存儲對象:

這一步跟上面使用Spring一樣,只需要將POJO類實現Serializable介面就可以了,我這裡就貼一下測試代碼:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest()
public class ApplicationTests {

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void test() throws Exception {

        User user = new User();
        user.setName("我沒有三顆心臟");
        user.setAge(21);

        redisTemplate.opsForValue().set("user_1", user);
        User user1 = (User) redisTemplate.opsForValue().get("user_1");

        System.out.println(user1.getName());
    }
}

仍然沒有任何問題:

參考文章:
1.https://www.cnblogs.com/ityouknow/p/5748830.html
2.http://blog.didispace.com/springbootredis/


在Redis中操作集合

引用文章:https://www.jianshu.com/p/29aaac3172b5

直接黏上兩段簡單的示例代碼:

在Redis中操作List

// list數據類型適合於消息隊列的場景:比如12306併發量太高,而同一時間段內只能處理指定數量的數據!必須滿足先進先出的原則,其餘數據處於等待
@Test
public void listPushResitTest() {
    // leftPush依次由右邊添加
    stringRedisTemplate.opsForList().rightPush("myList", "1");
    stringRedisTemplate.opsForList().rightPush("myList", "2");
    stringRedisTemplate.opsForList().rightPush("myList", "A");
    stringRedisTemplate.opsForList().rightPush("myList", "B");
    // leftPush依次由左邊添加
    stringRedisTemplate.opsForList().leftPush("myList", "0");
}

@Test
public void listGetListResitTest() {
    // 查詢類別所有元素
    List<String> listAll = stringRedisTemplate.opsForList().range("myList", 0, -1);
    logger.info("list all {}", listAll);
    // 查詢前3個元素
    List<String> list = stringRedisTemplate.opsForList().range("myList", 0, 3);
    logger.info("list limit {}", list);
}

@Test
public void listRemoveOneResitTest() {
    // 刪除先進入的B元素
    stringRedisTemplate.opsForList().remove("myList", 1, "B");
}

@Test
public void listRemoveAllResitTest() {
    // 刪除所有A元素
    stringRedisTemplate.opsForList().remove("myList", 0, "A");
}

在Redis中操作Hash

@Test
public void hashPutResitTest() {
    // map的key值相同,後添加的覆蓋原有的
    stringRedisTemplate.opsForHash().put("banks:12600000", "a", "b");
}

@Test
public void hashGetEntiresResitTest() {
    // 獲取map對象
    Map<Object, Object> map = stringRedisTemplate.opsForHash().entries("banks:12600000");
    logger.info("objects:{}", map);
}

@Test
public void hashGeDeleteResitTest() {
    // 根據map的key刪除這個元素
    stringRedisTemplate.opsForHash().delete("banks:12600000", "c");
}

@Test
public void hashGetKeysResitTest() {
    // 獲得map的key集合
    Set<Object> objects = stringRedisTemplate.opsForHash().keys("banks:12600000");
    logger.info("objects:{}", objects);
}

@Test
public void hashGetValueListResitTest() {
    // 獲得map的value列表
    List<Object> objects = stringRedisTemplate.opsForHash().values("banks:12600000");
    logger.info("objects:{}", objects);
}

@Test
public void hashSize() { // 獲取map對象大小
    long size = stringRedisTemplate.opsForHash().size("banks:12600000");
    logger.info("size:{}", size);
}

總結

在網上看到了關於MySQL的性能測試,讀寫操作大概就每秒1000以下的樣子,而且這還和引擎相關,所以可以看出Redis確實能在性能方面幫助許多

歡迎轉載,轉載請註明出處!
簡書ID:@我沒有三顆心臟
github:wmyskxz
歡迎關註公眾微信號:wmyskxz_javaweb
分享自己的Java Web學習之路以及各種Java學習資料


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在html文檔中,元素體現為一個一個的方形盒子。每個盒子由以下四種屬性來確定他在文檔中的位置和大小: content 內容區域 padding 內邊距 border 邊框 margin 外邊距 標準和非標準 在 定義下,content占據的空間由(min/max)width,(min/max)hei ...
  • 剛剛接觸前端開發,對於-webkit-font-smoothing: antialiased; 這個屬性不瞭解。上網查找了一些資料。 總結一下: -webkit-font-smoothing : 設置字體的抗鋸齒或光滑度的屬性。 有3個值: 1.none :無抗鋸齒 2.subpixel-antia ...
  • 第一步,安裝。進入項目目錄 npm install ng2-bootstrap bootstrap --save 第二步,angular-cli 配置 ng2-bootstrap src/.angular-cli.json 文件里"apps"項下的"styles"項,添加 bootstrap.min ...
  • 今天使用vue調試頁面,發現了頁面上的一個問題,後臺數據傳過來的HTML字元串並沒有被轉換為正常的HTML代碼,一拍腦門,發現忘記轉換了,於是滿心歡喜加上了{{{}}}。但是之後構建發現報錯: 為此去官網上查了下資料,發現在vue2.0版本中,{{{}}}轉換HTML的方式已經被廢除,該版本中必須使 ...
  • RPC傳輸 作為AMQP的實現,RabbitMQ使用RPC(remote procedure call)模式進行遠程會話。而不同於一般的RPC會話——客戶端發出指令,服務端響應,但服務端不會向客戶端發出指令;在AMQP規範中,服務端與客戶端皆會發出指令。 對於AMQP,客戶端首先發送protocol ...
  • 5月又即將要離我們遠去了,這個月有小長假51勞動節,有54青年節,有513母親節,更有坑爹的520神馬節?!! 廢話不說,又到了總結上個月乾貨的時候了,這個月我們帶來了各種Java技術乾貨,都是不得不看的 Java 實戰經驗及最新的熱門資訊。如果你有錯過本月乾貨,那麼你可以在這裡統一回顧一下。 "J ...
  • Java開源生鮮電商平臺-源碼地址公佈與思考和建議 說明:今天是承諾給大家的最後一天,我公佈了github地址(QQ群裡面有)。誠然這個是我的計劃中的事情,但是有以下幾點思考請大家共勉: 1. 你下了那麼多的github代碼,你學了多少呢?你又學會了多少呢? github的確是21世紀IT研發人員的 ...
  • 前言 在單體架構的秒殺活動中,為了減輕DB層的壓力,這裡我們採用了Lock鎖來實現秒殺用戶排隊搶購。然而很不幸的是儘管使用了鎖,但是測試過程中仍然會超賣,執行了N多次發現依然有問題。輸出一下代碼吧,可能大家看的比較真切: 代碼寫在service層,bean預設是單例的,也就是說lock肯定是一個對象 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...