信頼はずっと、挑戦はもっと。

お問い合わせ
TEL:03-3496-3888

BLOG コアテックの社員ブログ (毎週月曜~金曜更新中)

LIST OF ARTICLES

記事一覧

  • テクログ

    NuxtJs

    皆さんこんにちは。本日はNuxtjsというものを少し触ってみます結構前ですが同じくブログでVueJsを紹介しました。↓https://core-tech.jp/blog/article196/NuxtJsはこれに対して機能を足してSSR(サーバサイドレンダリング)を可能にしたフレームワークのようです。これだけSPAサイトが流行っている中ですが、クローラにちゃんとキーワードを読ませたいよってなったらこういったSSRができるフレームワークを使わないといけませんね。では早速。Nodejsがインストール済で、NPM5.2以降が入っている前提で話をします。私はOSはMACOS(Mojave)です。コンソールで以下を入力します。npx create-nuxt-app sample 初期設定コンソールがでるので適当に好みにあったものを選択します。で、おわるとこんな感じのがでます。 To get started: cd sample npm run dev  To build & start for production: cd sample npm run build npm run start To get startedの手順をそのまま叩くと起動します。 cd sample npm run dev で、http://localhost:3000にアクセス。はいできた。ここで終わっても面白くはないので少しだけいじって体験してみます。作成したプロジェクトにはすでにGitまで入っているので一応登録しておきます。同じ場所でgit add . git commit :wq デザインの部分に関しては、今回はBootsnippさんにサンプルとしてあるhttps://bootsnipp.com/snippets/1ea0Nを使わせてもらいます。いじるファイルは2ファイル★変更点sample/nuxt.config.jsheadの部分をまるっとこの形にします。head: {   title: 'nuxt-example',   meta: [     { charset: 'utf-8' },     { name: 'viewport', content: 'width=device-width, initial-scale=1' },     { hid: 'description', name: 'description', content: 'Nuxt.js project' }   ],   script: [     { src: 'https://maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js' },     { src: 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js' }   ],   link: [     { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },     { rel: 'stylesheet', id: 'bootstrap-css', href: 'https://maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css' },     { rel: 'stylesheet', type: 'text/css', href: 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css' },   ] }, これは、ページのヘッダなどを設定する部分で前回同様CDNでスタイルなど引けるようにしています。Sample/pages/index.vueまるっと下記を貼り付けます<template>   <div class="container">     <div class="messaging">       <div class="inbox_msg">         <div class="inbox_people">           <div class="headind_srch">             <div class="recent_heading">               <h4>Recent</h4>             </div>             <div class="srch_bar">               <div class="stylish-input-group">                 <input type="text" class="search-bar"  placeholder="Search" >                 <span class="input-group-addon">                 <button type="button"> <i class="fa fa-search" aria-hidden="true"></i> </button>                 </span> </div>             </div>           </div>           <div class="inbox_chat">             <div class="chat_list active_chat">               <div class="chat_people">                 <div class="chat_img"> <img src="https://ptetutorials.com/images/user-profile.png" alt="sunil"> </div>                 <div class="chat_ib">                   <h5>Coretec-Nuxt-Sample<span class="chat_date">Aug 6</span></h5>                   <p>テストのためのサンプルです</p>                 </div>               </div>             </div>             <div class="chat_list">               <div class="chat_people">                 <div class="chat_img"> <img src="https://ptetutorials.com/images/user-profile.png" alt="sunil"> </div>                 <div class="chat_ib">                   <h5>テストです<span class="chat_date">Aug 7</span></h5>                   <p>テスト部屋2番です</p>                 </div>               </div>             </div>           </div>         </div>         <div class="mesgs">           <div class="msg_history">             <div class="outgoing_msg">               <div class="sent_msg">                 <p>最初からいれてあるサンプルの部分です</p>                 <span class="time_date"> 11:01 AM    |    Today</span> </div>             </div>             <div class="incoming_msg">               <div class="incoming_msg_img"> <img src="https://ptetutorials.com/images/user-profile.png" alt="sunil"> </div>               <div class="received_msg">                 <div class="received_withd_msg">                   <p>最初からいれてあるサンプルの部分です                   </p>                   <span class="time_date"> 11:01 AM    |    Today</span></div>               </div>             </div>             <div v-for='(meg, index) in talks' :key='index' >               <div class="incoming_msg" v-if=meg.flg>                 <div class="incoming_msg_img"> <img src="https://ptetutorials.com/images/user-profile.png" alt="sunil"> </div>                 <div class="received_msg">                   <div class="received_withd_msg">                     <p>{{ meg.item }}</p>                     <span class="time_date">{{ meg.timestamp }}</span></div>                 </div>               </div>               <div class="outgoing_msg" v-else>                 <div class="sent_msg">                   <p>{{ meg.item }}</p>                   <span class="time_date">{{ meg.timestamp }}</span> </div>               </div>             </div>           </div>           <form v-on:submit.prevent>             <div class="type_msg">               <div class="input_msg_write">                 <input type="text" class="write_msg" placeholder="メッセージをいれてね" v-model="newItem" />                 <button class="msg_send_btn" type="button"><i class="fa fa-paper-plane-o" aria-hidden="true" v-on:click="addItem"></i></button>               </div>             </div>           </form>         </div>       </div>     </div></div> </template> <script>     export default {         data() {             return {                 newItem: '',                 talks: [],                 flg: false             }         },         methods: {             addItem: function(event) {               var val = this.flg               var todo = {                   item: this.newItem,                   timestamp:new Date(),                   flg:!val               };               this.flg = todo.flg               this.talks.push(todo)             }         }     } </script> <style>   .container {     min-height: 100vh;     display: flex;     justify-content: center;     align-items: center;     text-align: center;   }   .title {     font-family: "Quicksand", "Source Sans Pro", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; /* 1 */     display: block;     font-weight: 300;     font-size: 100px;     color: #35495e;     letter-spacing: 1px;   }   .subtitle {     font-weight: 300;     font-size: 42px;     color: #526488;     word-spacing: 5px;     padding-bottom: 15px;   }   .links {     padding-top: 15px;   }   .container{max-width:1170px; margin:auto;}   img{ max-width:100%;}   .inbox_people {     background: #f8f8f8 none repeat scroll 0 0;     float: left;     overflow: hidden;     width: 40%; border-right:1px solid #c4c4c4;   }   .inbox_msg {     border: 1px solid #c4c4c4;     clear: both;     overflow: hidden;   }   .top_spac{ margin: 20px 0 0;}   .recent_heading {float: left; width:40%;}   .srch_bar {     display: inline-block;     text-align: right;     width: 60%; padding:   }   .headind_srch{ padding:10px 29px 10px 20px; overflow:hidden; border-bottom:1px solid #c4c4c4;}   .recent_heading h4 {     color: #05728f;     font-size: 21px;     margin: auto;   }   .srch_bar input{ border:1px solid #cdcdcd; border-width:0 0 1px 0; width:80%; padding:2px 0 4px 6px; background:none;}   .srch_bar .input-group-addon button {     background: rgba(0, 0, 0, 0) none repeat scroll 0 0;     border: medium none;     padding: 0;     color: #707070;     font-size: 18px;   }   .srch_bar .input-group-addon { margin: 0 0 0 -27px;}   .chat_ib h5{ font-size:15px; color:#464646; margin:0 0 8px 0;}   .chat_ib h5 span{ font-size:13px; float:right;}   .chat_ib p{ font-size:14px; color:#989898; margin:auto}   .chat_img {     float: left;     width: 11%;   }   .chat_ib {     float: left;     padding: 0 0 0 15px;     width: 88%;   }   .chat_people{ overflow:hidden; clear:both;}   .chat_list {     border-bottom: 1px solid #c4c4c4;     margin: 0;     padding: 18px 16px 10px;   }   .inbox_chat { height: 550px; overflow-y: scroll;}   .active_chat{ background:#ebebeb;}   .incoming_msg_img {     display: inline-block;     width: 6%;   }   .received_msg {     display: inline-block;     padding: 0 0 0 10px;     vertical-align: top;     width: 92%;   }   .received_withd_msg p {     background: #ebebeb none repeat scroll 0 0;     border-radius: 3px;     color: #646464;     font-size: 14px;     margin: 0;     padding: 5px 10px 5px 12px;     width: 100%;   }   .time_date {     color: #747474;     display: block;     font-size: 12px;     margin: 8px 0 0;   }   .received_withd_msg { width: 57%;}   .mesgs {     float: left;     padding: 30px 15px 0 25px;     width: 60%;   }   .sent_msg p {     background: #05728f none repeat scroll 0 0;     border-radius: 3px;     font-size: 14px;     margin: 0; color:#fff;     padding: 5px 10px 5px 12px;     width:100%;   }   .outgoing_msg{ overflow:hidden; margin:26px 0 26px;}   .sent_msg {     float: right;     width: 46%;   }   .input_msg_write input {     background: rgba(0, 0, 0, 0) none repeat scroll 0 0;     border: medium none;     color: #4c4c4c;     font-size: 15px;     min-height: 48px;     width: 100%;   }   .type_msg {border-top: 1px solid #c4c4c4;position: relative;}   .msg_send_btn {     background: #05728f none repeat scroll 0 0;     border: medium none;     border-radius: 50%;     color: #fff;     cursor: pointer;     font-size: 17px;     height: 33px;     position: absolute;     right: 0;     top: 11px;     width: 33px;   }   .messaging { padding: 0 0 50px 0;}   .msg_history {     height: 516px;     overflow-y: auto;   } </style> で、何ができたかというと。一人でチャットできるWebアプリです(笑)初期画面こんな感じ『メッセージをいれてね』の部分に文字を入れて右の紙飛行機ボタンを押すと1人チャット完成です。処理部分に関して抜粋して書きます。Index.vueのHTML部分 <div class="mesgs">   <div class="msg_history">    <div class="outgoing_msg">     <div class="sent_msg">      <p>最初からいれてあるサンプルの部分です</p>      <span class="time_date"> 11:01 AM  |  Today</span> </div>    </div>    <div class="incoming_msg">     <div class="incoming_msg_img"> <img src="https://ptetutorials.com/images/user-profile.png" alt="sunil"> </div>     <div class="received_msg">      <div class="received_withd_msg">       <p>最初からいれてあるサンプルの部分です       </p>       <span class="time_date"> 11:01 AM  |  Today</span></div>     </div>    </div>    <div v-for='(meg, index) in talks' :key='index' >     <div class="incoming_msg" v-if=meg.flg>      <div class="incoming_msg_img"> <img src="https://ptetutorials.com/images/user-profile.png" alt="sunil"> </div>      <div class="received_msg">       <div class="received_withd_msg">        <p>{{ meg.item }}</p>        <span class="time_date">{{ meg.timestamp }}</span></div>      </div>     </div>     <div class="outgoing_msg" v-else>      <div class="sent_msg">       <p>{{ meg.item }}</p>       <span class="time_date">{{ meg.timestamp }}</span> </div>     </div>    </div>   </div>   <form v-on:submit.prevent>    <div class="type_msg">     <div class="input_msg_write">      <input type="text" class="write_msg" placeholder="メッセージをいれてね" v-model="newItem" />      <button class="msg_send_btn" type="button"><i class="fa fa-paper-plane-o" aria-hidden="true" v-on:click="addItem"></i></button>     </div>    </div>   </form>  </div> </div> Index.vueの処理部分<script>   export default {     data() {       return {         newItem: '',         talks: [],         flg: false       }     },     methods: {       addItem: function(event) {        var val = this.flg        var todo = {          item: this.newItem,          timestamp:new Date(),          flg:!val        };        this.flg = todo.flg        this.talks.push(todo)       }     }   } </script> buttonを押下した時にscriptのv-on:click="addItem"が発火。v-model="newItem”の値を入れてdataの変数を書き換え再描画しています。1メッセージごとにflgの中身を交互に切り替え自分と相手側が会話しているように表現しています。再描画部分は<div v-for='(meg, index) in talks' :key='index' >でループで出力し、<div class="incoming_msg" v-if=meg.flg>でHTMLを相互に切り替えています。わりと簡単な実装でチャットツールのような表現をすることができました。しっかりと作り込んでいけばもっと沢山のことができるかもしれませんね。本日はざっくり概要部分だけ触れました。それでは。
  • テクログ

    windows10 再セットアップ 復習

    先日windows10の再インストールを行った時の事です。windowsが起動している状態だったので普通にメニューから「このPCを初期状態に戻す」を選択したのですが、終わった後に初期セットアップに進むはずですが、エラーが出て一向に先に進みません。このエラーと言うのが、LANに繋いで更新すれば先に進むという感じでしたがLANケーブルを挿しても全く変わらず。何度再起動しても同じエラーがでて先に進む事ができませんでした。この時の失敗したかなと思ったポイントとしては1 更新とセキュリティから再インストールを選択していなかった※shiftを押しながら再起動から再インストールを選択した2 全てのドライブを選択していなかったリカバリ領域まで削除されると思いwindowsがインストールされているドライブのみを選択した1に関してはおそらく問題がないと思われます。各メーカーさんのHPでもその手順を紹介している物もあるのでどちらから入っても問題がないと思われます。2に関しては全てのドライブを削除するので時間がかかると思い選択しなかったので、問題があるとすればコチラかなと思う所です。結局ディスクから再インストールを行い無事に起動しました。起動後に次は別の手順でやり直してみた所問題なくインストールが完了しました。楽なのはHDDリカバリですが、メディアを使ったやり方に慣れている人ならば慣れている分失敗しにくいのではないかと思います。※各メーカーによって若干表記等が違う場合があります。
  • テクログ

    ISUCON8の予選問題について、環境構築してみる

    ISUCON8の環境構築してみたISUCON、ご存知ですか?http://isucon.net/一言でいうと、WEBサービスのチューニングバトルです1回も出たことないですが、毎回盛り上がってるみたいです。今回はISUCON8の予選問題の環境構築をやってみました。公式やGitにもいろいろ書いてあるのですが・・・かなり苦戦しました・・・vagrantが入っていることが前提です。あとPHPです。1.ここに予選のアプリケーションのソースがあがっているので、自分のPCの好きなところにcloneしましょうhttps://github.com/isucon/isucon8-qualify2.ここに各種vagrantの設定ファイル等があるので、今回はisucon8-qualifier-standaloneで(一台構成ver)ファイルを落としてきて1と同じディレクトリにvagrantfileを置きますhttps://github.com/matsuu/vagrant-isucon3.vagrant up どん!4.vagrant up したら、vagrant sshします5.https://github.com/isucon/isucon8-qualifyここ 環境構築に書かれてることをひたすらやる6.PHPで動かしたいので初期でperlが起動しているのを停止してphpを起動sudo systemctl stop  torb.perl sudo systemctl disable torb.perl sudo systemctl start  torb.php sudo systemctl enable torb.php 7.phpでwebサイト見るためにh2oのconfファイルシンボリックリンク貼り直しと再起動sudo rm /etc/h2o/h2o.conf sudo ln -s /etc/h2o/php-h2o.conf /etc/h2o/h2o.conf sudo systemctl restart h2o 8.mariadbが起動していないので起動sudo service mariadb start 9.DBに初期データ流し込むためにシェル実行/home/isucon/torb/db/init.sh 10.vagrantfileに書いてあるIPにアクセスこれで画面が見れるはず・・・!!!!ですベンチもvagrantで実行すると初期の点数が見れるはず・・・です!!
  • テクログ

    AWS CLIを使ってIAMユーザーの登録から二段階認証をオンにするまでのスクリプト

    नमस्ते! आप कैसे(कैसी) हैं?ナマステー!こんにちは。インフラ担当のまつやです。弊社ではWebサービスの基盤としてAWS(Amazon Web Service)を主に使っています。エンジニアはAWSコンソールからログインして作業することが多いため、メンバーが増えるたびにアカウントを発行する必要があります。このアカウント作成はAWSコンソールにログインし、IAM(Identity and Access Management)から作成できますが、発行頻度が増えてくるとGUIからのアカウントの発行・通知がやや大変になってきました。そこで、AWS CLI(コマンドラインインターフェイス)を利用して、ユーザー発行に必要なコマンド操作を一括で行えるシェルスクリプトを作成することにしました。また弊社ではAWSコンソールからのログインにパスワード設定の上、MFAデバイスによる二段階認証を必須としています。この二段階認証も同時に設定してしまい、パスワード情報と二段階認証用のQRコードをユーザーに通知するだけで済むようにしたいと思います。Amazon Linuxのbash環境で作成しています。python(2.7)aws-cli(最新版)oathtoolが必要になります。以下が本体のシェルスクリプトです。#!/bin/bash set -e # 環境変数設定 export BASE_DIR=${HOME}/iam # # usage # usage_exit() {  echo "usage:"  echo "${0} -u USERNAME [-g GROUP] [-a] [-h]" 1>&2  echo "-a: create API key for each user." 1>&2  echo "-h: this help." 1>&2  exit 1 } #パスワード生成コマンド password_command="cat /dev/urandom | tr -dc '12345678abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ+\-!' | fold -w 16 | grep -E '[123456789]' | grep -E '[+\-\!]' | grep -E '^[123456789abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ]' |head -n 1" #引数の設定 while getopts "u:g:h" OPT do    case $OPT in        "u") CREATE_USER="true"; username=${OPTARG}            ;;        "g") ADD_TO_GROUP="true"; group=${OPTARG}            ;;        "h") usage_exit            ;;        \?) usage_exit            ;;    esac done # 引数でユーザーを指定しない場合終了する。 [ "${CREATE_USER}" != "true" ] && usage_exit #IAMユーザーのクレデンシャル情報格納用のディレクトリを作成。  if [ "${CREATE_USER}" = "true" ]; then      if [ ! -e "${BASE_DIR}/account/${username}" ]; then        mkdir -p ${BASE_DIR}/account/${username}      else       echo "Directory ${username} already exists."      fi #IAMユーザー作成   aws iam create-user --user-name ${username} --profile default   aws iam wait user-exists --user-name ${username} #二段階認証の仮想MFAデバイスを作成   aws iam create-virtual-mfa-device --virtual-mfa-device-name ${username} \   --bootstrap-method Base32StringSeed \   --outfile ${BASE_DIR}/account/${username}/${username}_secret.txt #クレデンシャル情報ファイルに出力する内容  secret_key=`cat ${BASE_DIR}/account/${username}/${username}_secret.txt`  signin_url="https://AWSアカウント名.signin.aws.amazon.com/console"  password=$(eval ${password_command}) #ログインパスワードの設定&初回ログイン時のパスワード強制変更をオンにする   aws iam create-login-profile --user-name $username \   --password ${password} --password-reset-required --profile default #クレデンシャル情報をファイルに出力 echo "User name,Password,Secret access key,Console login link ${username},${password},${secret_key},${signin_url}" > ${BASE_DIR}/account/${username}/${username}_password.csv #二段階認証用のQRコードを生成  python /home/ec2-user/iam/qrcodegen.py "otpauth://totp/Amazon%20Web%20Services:${username}@AWSアカウント名?secret=${secret_key}&issuer=Amazon%20Web%20Services" ${BASE_DIR}/account/${username}/${username}_qr.png # Login Profile が完全にできているか確認してから次へ進む  aws iam wait user-exists --user-name ${username} #ワンタイムパスワードを発行する code="oathtool --totp -d 6 --time-step-size=30s --base32 ${secret_key}"        code1=$(eval ${code})        while :         do           code2=$(eval ${code})            if [ $code2 != $code1 ]; then                 break;            fi         done #二段階認証をオンにする  aws iam enable-mfa-device --user-name ${username} \  --serial-number arn:aws:iam::XXXXXXXXXXXX:mfa/${username} \  --authentication-code1 ${code1} --authentication-code2 ${code2} #(注: arn:aws:iam::XXXXXXXXXXXX:mfa の12桁のXXXXXXXXXXXXにはAWSアカウントIDが入ります)  else  usage_exit  fi # 引数で-gを指定した場合 ユーザー ${username} にグループ ${group} を割り当てる  if [ "${ADD_TO_GROUP}" = "true" ]; then     aws iam wait user-exists --user-name ${username}     aws iam add-user-to-group --group-name ${group} \     --user-name ${username} \     --profile default  fi -u username の形式でユーザー名の指定を必須にしています。ここで指定したユーザー名を使って処理が進みます。まず、基本のIAMユーザー作成を行います。aws iam wait user-existsでユーザーが作成されたことを確認して先に進みます。次に二段階認証用の仮想MFAデバイスを作成します。AWSコンソールから作成する場合はIAMユーザーと同じ名前で作成されますが、CLIで作成する場合はデバイス名が重複しない限りはIAMユーザー名と異なっていても別の名前のデバイスを作成し、関連付けをすることができます。ここでは管理が面倒になるので、IAMユーザ名と一致させます。MFAデバイス作成と同時にシークレットキーを発行します。ここではQRコードの形でも発行できますが、シークレットキーと同時に発行することができないため、シークレットキーを発行し、そのシークレットキーを元に別途QRコードを作成します。次にログインパスワードを設定します。初回ログイン時に強制的にパスワード変更させるオプションを有効にします。この時発行するパスワードですが、cat /dev/urandomして tr -dcとかで切り出して、16文字のものを生成しています。小文字のエル、数字の0と大文字小文字のオーは除外しています。パスワードコマンドはこれに限らずpwgenとかが使えるならそれでいいかと思います。次にQRコードの生成です。pythonのqrcodeライブラリを使います。pipでインストールします。pip install qrcode インストールしたら、中間プログラムを作成します。ここではqrcodegen.pyとしています。qrcodegen.pyimport qrcode import sys import os args = sys.argv qr = qrcode.QRCode(  version=4,  error_correction=qrcode.constants.ERROR_CORRECT_M,  box_size=6,  border=4, ) qr.data = args[1] qr.save_path = args[2] qr.add_data(qr.data, 20) qr.make(fit=True) img = qr.make_image(fill_color="black", back_color="white") img.save(qr.save_path) これを使ってQRコードを生成します。MFAデバイスを作成したときの ${username}_secret.txt を${secret_key}に指定します。${username}@AWSアカウントの箇所はご自身の環境に合わせて読み替えて下さい。これでIAMユーザー毎のクレデンシャル情報格納ディレクトリにQRコードが生成されます。二段階認証を有効にします。oathtoolを使用してワンタイムパスワードを発行します。これを都合2回入力することで二段階認証が有効になります。Amazon Linuxでは基本のリポジトリには存在しないので、epelリポジトリからインストールします。epelリポジトリを有効にする方法はここでは割愛します。発行したシークレットキーを元に6桁のワンタイムパスワードを発行します。whileでこのパスワード発行コマンドを実行し、初めにに発行した値と異なる値になるまで回します。ここでcode1とcode2を取得します。code1とcode2を使って二段階認証をオンにします。最後に-gでグループを引数に指定した場合の処理です。指定したグループをユーザーに割当てます。指定しなければスルーします。以上のようにして、事前に二段階認証をオンにした状態でIAMユーザー情報を各エンジニアに展開しています。エンジニアは発行されたパスワードとQRコード、あるいはシークレットキーを元にAWSコンソールにログインできます。この他に、二段階認証がオフになっているユーザーがいないかを監視するLambdaのスクリプトも作成していますが、それについてはまたの機会に。・参考にした記事 https://dev.classmethod.jp/etc/aws-cli-iamuser-bulk-create/ https://dev.classmethod.jp/cloud/aws/virtual-mfa-by-aws-cli/それではまた!फिर मिलेंगे!
  • テクログ

    高機能スライダー「Swiper」の魅力的なオプションについて

    こんにちは、ささです。今回は高機能スライダーの大定番「Swiper」の魅力的なオプションを使った実装サンプルを一部ご紹介します!色々なスライダープラグイン試してみましたが、個人的にこれが一番使いやすいプラグインではないかと思っています。◆Swiperとはhttps://codepen.io/HOanhhOanhh/pen/eorEVR/レスポンシブ対応やスワイプ操作が可能なため、スマホサイトへの実装がしやすく、前・次ボタン、ページネーション、スクロールバー、スライド速度、エフェクトなど様々なオプションを備えた高機能プラグインです。※実装方法や設定の詳細は、下記URLをご参照ください。http://idangero.us/swiper/get-started/基本的な設定をするだけで、シンプルなスライダーの実装が可能ですが、Swiperの魅力は豊富なオプションだと思います。様々なオプションを駆使すれば、以下のような面白い動きをさせることが可能です。◆実装サンプル・Swiper Cover Flow Sliderhttps://codepen.io/michiel-huiskens/pen/jMjozYメイン画像を中央に表示し3Dでスライドが切り替わる、カバーフロー効果を使用したスライダー・3D Cube Slider with Swiper.jshttps://codepen.io/digistate/pen/OzOZgY四角い箱がくるくる回転する、キューブ効果を使用した3D回転スライダー・Slider transitionshttps://codepen.io/fluxus/pen/rweVgp縦スクロールとパララックス効果を使用したスライダーこれらはほんの一部のオプションで作られたもので、Swiperにはまだまだ多くのオプションが存在します。※ご興味ある方は、下記URLをご参照ください。http://idangero.us/swiper/api/#parametersSwiperを使いこなして、より魅力的なスライダーを実装してみてはいかがでしょうか!
  • テクログ

    スワップのお話

    若いエンジニアとの技術的乖離をどうにかせねばっ!・・・と、今時の技術を猛勉強している老兵エンジニアの大西です。さて、今回は少し前に行った技講時にも質問がありましたのでスワップのお話を少し記そうと思います。サーバを扱うWeb屋としては基本中の基本ですが良かったら読んでみて下さいね。スワップの前にメモリーのおさらいなどメモリーといっても容量(サイズ)ではなく領域のお話になるのですが・・・メモリ上にはザックリとおおまかに2種類の領域が存在しますよね。1つは「ユーザプロセス空間」で、もう1つが「ファイルキャッシュ」。この2種類の領域においてshrinkの比率が設定されていて、この設定を司っているのが vm.swappiness となります。(shrink: 解放あるいはスワップアウト)vm.swappinessこの vm.swappiness ですがカーネル 2.6.32-303 を境にその意味が大きく変更されました。2.6.32-303未満では[vm.swappiness=0]は最小比率となりユーザプロセス空間をshrinkします。一方2.6.32-303以降では[vm.swappiness=0]の時はユーザプロセス空間はshrinkされません。これは2.6.32-303以降、つまり現カーネルにおいては[vm.swappiness=0]だと解放可能な使用済ユーザプロセス空間が残り続ける事が予想されるので、[vm.swappiness=0]ではなく[vm.swappiness=1]の方が良いのだ・・・となるわけです。メモリーおさらい基礎知識サーバを扱っているエンジニアの方はよくよく目にすると思いますがあらためて記してみます。Anonymous Memory[Pages]スワップが必要でかつ解放不可能なメモリー。ユーザプロセス空間などがこれに当たります。File-backed Memory[Pages]ディスクなどへ書き出す事で解放可能なメモリーです。/proc/meminfo を見てみるActive(anon)匿名ページのアクティブ分Inactive(anon)終了プロセスなどの解放可能な匿名ページActive(file)File-backedのアクティブ分Inactive(file)解放可能なFile-backedAnonPages約 Active(anon) + Inactive(anon)Buffers + Cached約 Active(file) + Inactive(file)vm.swappiness=100 とは?この状態は Anonymous と File-backed のスワップ比率が同じ状態になります。カーネルのプログラム関数 get_scan_ratio() において、anon_prio = sc->swappiness;file_prio = 200 - sc->swappiness;とあり、[vm.swappiness=100]の場合は anon_prio も file_prio も同じスワップ比率となります。カーネルを覗いてみるmm/vmscan.c に get_scan_ratio() があります。  static void get_scan_ratio(・・・) {    anon_prio = sc->swappiness;    file_prio = 200 - sc->swappiness;    // vm.swappiness=0 の場合は常に ap=0    ap = anon_prio * (reclaim_stat->recent_scanned[0] + 1);    ap /= reclaim_stat->recent_rotated[0] + 1;    fp = file_prio * (reclaim_stat->recent_scanned[1] + 1);    fp /= reclaim_stat->recent_rotated[1] + 1;    /* Normalize to percentages */    percent[0] = 100 * ap / (ap + fp + 1);  <- Anonymousの比率は ap=0 なので 0    percent[1] = 100 - percent[0];  <- こちらは File-backedの比率[vm.swappiness=0]にすると Anonymous の比率が 0 なのでスワップが発生しない事になりますね。実験してみたメモリー数十メガバイトという仮想サーバを作りそのサーバ上で数ギガバイトの圧縮データを zless してみた。vm.swappiness=0 -> スワップは発生しませんが、OOM Killer が発生しました。vm.swappiness=1 -> スワップが発生しましたが、プロセスはダウンしませんでした。結論今時の Linux でスワップをぎりぎりまで我慢させたい場合は、vm.swappiness を 0 にするのではなく 1 にしよう。ちなみに OOM Killer についてもよく技講にて質問されます。気が向いたら次回のブログ担当の時にでも。